123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095 |
- From c433730d889d0dfb31bdcf4f102ca47939606c46 Mon Sep 17 00:00:00 2001
- From: remittor <[email protected]>
- Date: Fri, 11 Aug 2023 12:08:30 +0300
- Subject: [PATCH] ipq806x: Add support for Xiaomi Mi Router HD (R3D)
- Xiaomi R3D is a 2.4/5 GHz band 11ac router, based on IPQ8064.
- Specification:
- * SoC: Qualcomm IPQ8064
- * RAM: 512MB DDR3
- * Flash: 256MB NAND (Macronix MX30UF2G18AC-TI)
- * Ethernet: 4x 10/100/1000 Mbps (1x WAN, 3x LAN)
- * WiFi: Qualcomm QCA9984 (5GHz, 4T4R, n/ac)
- * WiFi: Qualcomm QCA9980 (2.4GHz, 4T4R, b/g/n)
- * USB: 1x 3.0
- * SATA: 1x SATA 3.1 (only for internal HDD 3.5")
- * BTN: Power, Reset
- * LEDS: Status(Green/Blue/Red)
- * UART: present as 4-pads on the PCB (3.3V, 115200-8-N-1)
- MAC addresses as verified by stock firmware:
- | Interface | MAC | ART | Format |
- |-------------+-------------------+---------+--------|
- | WAN (label) | xx:xx:xx:xx:xx:B2 | 0x0 | binary |
- | LAN | xx:xx:xx:xx:xx:B3 | 0x6 | binary |
- | WiFi 2g | xx:xx:xx:xx:xx:B4 | 0x1006 | binary |
- | WiFi 5g | xx:xx:xx:xx:xx:B5 | 0x5006 | binary |
- ---
- package/boot/uboot-envtools/files/ipq806x | 6 +-
- .../ipq806x/base-files/etc/board.d/02_network | 4 +
- .../etc/hotplug.d/firmware/11-ath10k-caldata | 6 +
- .../ipq806x/base-files/etc/init.d/bootcount | 8 +
- .../base-files/lib/upgrade/platform.sh | 3 +
- .../ipq806x/base-files/lib/upgrade/xiaomi.sh | 441 ++++++++++++++++
- .../arch/arm/boot/dts/qcom-ipq8064-r3d.dts | 479 ++++++++++++++++++
- target/linux/ipq806x/image/generic.mk | 17 +
- 8 files changed, 963 insertions(+), 1 deletion(-)
- create mode 100644 target/linux/ipq806x/base-files/lib/upgrade/xiaomi.sh
- create mode 100644 target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-r3d.dts
- diff --git a/package/boot/uboot-envtools/files/ipq806x b/package/boot/uboot-envtools/files/ipq806x
- index 01a86c7b19fca..c0a781c1e21b4 100644
- --- a/package/boot/uboot-envtools/files/ipq806x
- +++ b/package/boot/uboot-envtools/files/ipq806x
- @@ -52,6 +52,10 @@ qcom,ipq8064-ap148|\
- qcom,ipq8064-db149)
- ubootenv_add_uci_config $(ubootenv_mtdinfo)
- ;;
- +xiaomi,r3d)
- + ubootenv_add_uci_config "/dev/mtd9" "0x0" "0x10000" "0x10000"
- + ubootenv_add_uci_sys_config "/dev/mtd12" "0x0" "0x10000" "0x10000"
- + ;;
- ubnt,unifi-ac-hd|\
- zyxel,nbg6817)
- ubootenv_add_uci_config "/dev/mtdblock9" "0x0" "0x10000" "0x10000"
- @@ -59,6 +63,6 @@ zyxel,nbg6817)
- esac
-
- config_load ubootenv
- -config_foreach ubootenv_add_app_config ubootenv
- +config_foreach ubootenv_add_app_config
-
- exit 0
- diff --git a/target/linux/ipq806x/base-files/etc/board.d/02_network b/target/linux/ipq806x/base-files/etc/board.d/02_network
- index 8dd52452b1739..df27cbde7c5d8 100644
- --- a/target/linux/ipq806x/base-files/etc/board.d/02_network
- +++ b/target/linux/ipq806x/base-files/etc/board.d/02_network
- @@ -89,6 +89,10 @@ nokia,ac400i |\
- ubnt,unifi-ac-hd)
- ucidef_set_interface_lan "eth0 eth1"
- ;;
- +xiaomi,r3d)
- + ucidef_add_switch "switch0" \
- + "1:lan:3" "2:lan:2" "3:lan:1" "6@eth1" "5:wan" "0@eth0"
- + ;;
- zyxel,nbg6817)
- hw_mac_addr=$(mtd_get_mac_ascii 0:appsblenv ethaddr)
- ucidef_add_switch "switch0" \
- diff --git a/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
- index 4c5019cf5bd24..aa8ed06aae4b3 100644
- --- a/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
- +++ b/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
- @@ -56,6 +56,9 @@ case "$FIRMWARE" in
- caldata_extract "0:art" 0x1000 0x2f20
- ath10k_patch_mac $(macaddr_add $(mtd_get_mac_ascii 0:appsblenv ethaddr) +2)
- ;;
- + xiaomi,r3d)
- + caldata_extract "ART" 0x1000 0x2f20
- + ;;
- zyxel,nbg6817)
- caldata_extract "0:art" 0x1000 0x2f20
- ath10k_patch_mac $(macaddr_add $(mtd_get_mac_ascii 0:appsblenv ethaddr) 1)
- @@ -92,6 +95,9 @@ case "$FIRMWARE" in
- caldata_extract "0:art" 0x5000 0x2f20
- ath10k_patch_mac $(macaddr_add $(mtd_get_mac_ascii 0:appsblenv ethaddr) +3)
- ;;
- + xiaomi,r3d)
- + caldata_extract "ART" 0x5000 0x2f20
- + ;;
- zyxel,nbg6817)
- caldata_extract "0:art" 0x5000 0x2f20
- ath10k_patch_mac $(mtd_get_mac_ascii 0:appsblenv ethaddr)
- diff --git a/target/linux/ipq806x/base-files/etc/init.d/bootcount b/target/linux/ipq806x/base-files/etc/init.d/bootcount
- index cb32a4ed3568d..9d9ab3f100fe2 100755
- --- a/target/linux/ipq806x/base-files/etc/init.d/bootcount
- +++ b/target/linux/ipq806x/base-files/etc/init.d/bootcount
- @@ -16,5 +16,13 @@ boot() {
- linksys,ea8500)
- mtd resetbc s_env || true
- ;;
- + xiaomi,r3d)
- + local boot_wait=$( fw_printenv boot_wait | cut -d = -f 2 )
- + [ "$boot_wait" != "on" ] && fw_setenv boot_wait on
- + local bootdelay=$( fw_printenv bootdelay | cut -d = -f 2 )
- + [ "$bootdelay" != "3" ] && fw_setenv bootdelay 3
- + local uart_en=$( fw_printenv uart_en | cut -d = -f 2 )
- + [ "$uart_en" != "1" ] && fw_setenv uart_en 1
- + ;;
- esac
- }
- diff --git a/target/linux/ipq806x/base-files/lib/upgrade/platform.sh b/target/linux/ipq806x/base-files/lib/upgrade/platform.sh
- index 5ec4f513bd33d..b142fce86a082 100644
- --- a/target/linux/ipq806x/base-files/lib/upgrade/platform.sh
- +++ b/target/linux/ipq806x/base-files/lib/upgrade/platform.sh
- @@ -71,6 +71,9 @@ platform_do_upgrade() {
- MTD_CONFIG_ARGS="-s 0x200000"
- default_do_upgrade "$1"
- ;;
- + xiaomi,r3d)
- + platform_do_upgrade_xiaomi "$1" 0x2800000
- + ;;
- zyxel,nbg6817)
- zyxel_do_upgrade "$1"
- ;;
- diff --git a/target/linux/ipq806x/base-files/lib/upgrade/xiaomi.sh b/target/linux/ipq806x/base-files/lib/upgrade/xiaomi.sh
- new file mode 100644
- index 0000000000000..9246e8f867e3f
- --- /dev/null
- +++ b/target/linux/ipq806x/base-files/lib/upgrade/xiaomi.sh
- @@ -0,0 +1,441 @@
- +# SPDX-License-Identifier: GPL-2.0-or-later OR MIT
- +
- +. /lib/functions.sh
- +
- +MAGIC_XIAOMI_HDR1="48445231" # "HDR1" - xiaomi image header
- +MAGIC_XIAOMI_BLK="beba0000"
- +MAGIC_UIMAGE="27051956" # uImage header
- +MAGIC_UBI="55424923" # "UBI#"
- +MAGIC_UBIFS="31181006"
- +MAGIC_HSQS="68737173" # "hsqs"
- +MAGIC_SYSUPG="7379737570677261" # TAR "sysupgrade"
- +
- +XIAOMI_PAGESIZE=2048
- +
- +XIAOMI_FW_FILE=""
- +XIAOMI_FW_SIZE=0
- +XIAOMI_KERNEL_PART=$CI_KERNPART
- +XIAOMI_KERNEL2_PART=""
- +XIAOMI_KERNEL2_NAMES="kernel_stock|kernel_dup"
- +XIAOMI_ROOTFS_PART=$CI_UBIPART
- +XIAOMI_ROOTFS_PARTSIZE=
- +
- +XIAOMI_RESTORE_ROOTFS2=
- +
- +log_msg() {
- + echo "$@"
- +}
- +
- +log_err() {
- + echo "ERROR: $@" >&2
- +}
- +
- +die() {
- + log_err "$@"
- + exit 1
- +}
- +
- +get_uint32_at() {
- + local offset=$1
- + local endianness=$2
- + local hex
- + if [ $(( $offset + 4 )) -gt $XIAOMI_FW_SIZE ]; then
- + echo ""
- + return
- + fi
- + local dd_args="if=$XIAOMI_FW_FILE skip=$offset bs=1 count=4"
- + if [ "$endianness" = "be" ]; then
- + hex=$( dd $dd_args 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' )
- + else
- + hex=$( dd $dd_args 2>/dev/null | hexdump -v -e '1/4 "%02x"' )
- + fi
- + echo $( printf "%d" 0x$hex )
- +}
- +
- +get_hexdump_at() {
- + local offset=$1
- + local size=$2
- + if [ $(( $offset + $size )) -gt $XIAOMI_FW_SIZE ]; then
- + echo ""
- + return
- + fi
- + local dd_args="if=$XIAOMI_FW_FILE skip=$offset bs=1 count=$size"
- + echo $( dd $dd_args 2>/dev/null | hexdump -v -n $size -e '1/1 "%02x"' )
- +}
- +
- +get_round_up() {
- + local value=$1
- + local base=$2
- + local pad=0
- + if [ -z "$base" ]; then
- + base=$XIAOMI_PAGESIZE
- + else
- + base=$( printf "%d" $base )
- + fi
- + if [ $(( $value % $base )) != 0 ]; then
- + pad=$(( $base - $value % $base ))
- + fi
- + echo $(( $value + $pad ))
- +}
- +
- +get_part_size() {
- + local part_name=$1
- + local part=$( cat /proc/mtd | grep \"$part_name\" )
- + if [ -z "$part" ]; then
- + echo 0
- + else
- + local mtd_size_hex=$( echo $part | awk '{print "0x"$2}' )
- + echo $( printf "%d" $mtd_size_hex )
- + fi
- +}
- +
- +xiaomi_check_sizes() {
- + local part_name=$1
- + local img_offset=$2
- + local img_size=$3
- +
- + local mtd_size=$( get_part_size $part_name )
- + if [ "$mtd_size" = "0" ]; then
- + echo "cannot find mtd partition with name '$part_name'"
- + return 1
- + fi
- + local img_end=$(( $img_offset + $img_size ))
- + if [ $img_end -gt $XIAOMI_FW_SIZE ]; then
- + echo "incorrect image size (part: '$part_name')"
- + return 1
- + fi
- + if [ $img_size -gt $mtd_size ]; then
- + echo "image is greater than partition '$part_name'"
- + return 1
- + fi
- + echo ""
- + return 0
- +}
- +
- +xiaomi_mtd_write() {
- + local part_name=$1
- + local img_offset=$2
- + local img_size=$3
- + local part_skip=$4
- +
- + img_size=$( get_round_up $img_size )
- + local err=$( xiaomi_check_sizes $part_name $img_offset $img_size )
- + if [ -n "$err" ]; then
- + log_err $err
- + return 1
- + fi
- + if [ -n "$part_skip" ]; then
- + part_skip="-p $part_skip"
- + fi
- + local count=$(( $img_size / $XIAOMI_PAGESIZE ))
- + local dd_args="if=$XIAOMI_FW_FILE iflag=skip_bytes skip=$img_offset bs=$XIAOMI_PAGESIZE count=$count"
- + dd $dd_args | mtd -f $part_skip write - "$part_name" || {
- + log_err "Failed to flash '$part_name'"
- + return 1
- + }
- + return 0
- +}
- +
- +xiaomi_flash_images() {
- + local kernel_offset=$1
- + local kernel_size=$2
- + local rootfs_offset=$3
- + local rootfs_size=$4
- + local err
- + local part_skip=0
- +
- + kernel_size=$( get_round_up $kernel_size )
- + rootfs_size=$( get_round_up $rootfs_size )
- +
- + err=$( xiaomi_check_sizes $XIAOMI_KERNEL_PART $kernel_offset $kernel_size )
- + [ -n "$err" ] && { log_err $err; return 1; }
- +
- + if [ -n "$XIAOMI_KERNEL2_PART" ]; then
- + err=$( xiaomi_check_sizes $XIAOMI_KERNEL2_PART $kernel_offset $kernel_size )
- + [ -n "$err" ] && { log_err $err; return 1; }
- + fi
- +
- + err=$( xiaomi_check_sizes $XIAOMI_ROOTFS_PART $rootfs_offset $rootfs_size )
- + [ -n "$err" ] && { log_err $err; return 1; }
- +
- + if [ "$XIAOMI_RESTORE_ROOTFS2" = "true" -a -n "$XIAOMI_ROOTFS_PARTSIZE" ]; then
- + part_skip=$( printf "%d" $XIAOMI_ROOTFS_PARTSIZE )
- + if [ $part_skip -lt 1000000 ]; then
- + part_skip=0
- + fi
- + fi
- +
- + if [ $part_skip -gt 0 ]; then
- + local ksize=$(( $part_skip + $rootfs_size ))
- + local mtd_size=$( get_part_size $XIAOMI_ROOTFS_PART )
- + if [ $ksize -gt $mtd_size ]; then
- + log_err "double rootfs is greater than partition '$XIAOMI_ROOTFS_PART'"
- + return 1
- + fi
- + fi
- +
- + mtd erase "$XIAOMI_ROOTFS_PART" || {
- + log_err "Failed to erase partition '$part_name'"
- + return 1
- + }
- +
- + xiaomi_mtd_write $XIAOMI_KERNEL_PART $kernel_offset $kernel_size || {
- + log_err "Failed flash data to '$XIAOMI_KERNEL_PART' partition"
- + return 1
- + }
- + log_msg "Kernel image flashed to '$XIAOMI_KERNEL_PART'"
- +
- + if [ -n "$XIAOMI_KERNEL2_PART" ]; then
- + xiaomi_mtd_write $XIAOMI_KERNEL2_PART $kernel_offset $kernel_size || {
- + log_err "Failed flash data to '$XIAOMI_KERNEL2_PART' partition"
- + return 1
- + }
- + log_msg "Kernel image flashed to '$XIAOMI_KERNEL2_PART'"
- + fi
- +
- + xiaomi_mtd_write $XIAOMI_ROOTFS_PART $rootfs_offset $rootfs_size || {
- + log_err "Failed flash data to '$XIAOMI_ROOTFS_PART' partition"
- + return 1
- + }
- + log_msg "Rootfs image flashed to '$XIAOMI_ROOTFS_PART'!"
- +
- + if [ $part_skip -gt 0 ]; then
- + xiaomi_mtd_write $XIAOMI_ROOTFS_PART $rootfs_offset $rootfs_size $part_skip || {
- + log_err "Failed flash data to '$XIAOMI_ROOTFS_PART' partition (2)"
- + return 1
- + }
- + log_msg "Rootfs image flashed to '$XIAOMI_ROOTFS_PART':$XIAOMI_ROOTFS_PARTSIZE"
- + fi
- +
- + log_msg "Firmware write successful! Reboot..."
- + sync
- + umount -a
- + reboot -f
- + exit 0
- +}
- +
- +check_ubi_header() {
- + local offset=$1
- +
- + local magic=$( get_hexdump_at $offset 4 )
- + [ "$magic" != $MAGIC_UBI ] && { echo ""; return 1; }
- +
- + local magic_ubi2="55424921" # "UBI!"
- + offset=$(( $offset + $XIAOMI_PAGESIZE ))
- + magic=$( get_hexdump_at $offset 4 )
- + [ "$magic" != $magic_ubi2 ] && { echo ""; return 1; }
- +
- + echo "true"
- + return 0
- +}
- +
- +get_rootfs_offset() {
- + local start=$1
- + local pos offset align end
- +
- + for offset in 0 1 2 3 4; do
- + pos=$(( $start + $offset ))
- + [ -n "$( check_ubi_header $pos )" ] && { echo $pos; return 0; }
- + done
- +
- + for align in 4 8 16 32 64 128 256 512 1024 2048 4096; do
- + pos=$( get_round_up $start $align )
- + [ -n "$( check_ubi_header $pos )" ] && { echo $pos; return 0; }
- + done
- +
- + align=65536
- + pos=$( get_round_up $start $align )
- + end=$(( $pos + 3000000 ))
- + while true; do
- + [ $(( $pos + 150000 )) -gt $XIAOMI_FW_SIZE ] && break
- + [ -n "$( check_ubi_header $pos )" ] && { echo $pos; return 0; }
- + pos=$(( $pos + $align ))
- + [ $pos -ge $end ] && break
- + done
- +
- + echo ""
- + return 1
- +}
- +
- +xiaomi_do_factory_upgrade() {
- + local err
- + local magic
- + local kernel_offset kernel_size
- + local rootfs_offset rootfs_size
- +
- + local kernel_mtd="$( find_mtd_index $XIAOMI_KERNEL_PART )"
- + if [ -z "$kernel_mtd" ]; then
- + log_err "partition '$XIAOMI_KERNEL_PART' not found"
- + return 1
- + fi
- + log_msg "Forced factory upgrade..."
- +
- + kernel_offset=0
- + kernel_size=$( get_uint32_at 12 "be" )
- + kernel_size=$(( $kernel_size + 64 ))
- +
- + rootfs_offset=$( get_rootfs_offset $kernel_size )
- + if [ -z "$rootfs_offset" ]; then
- + log_err "can't find ubinized rootfs in the firmware image"
- + return 1
- + fi
- + rootfs_size=$(( $XIAOMI_FW_SIZE - $rootfs_offset ))
- + local rootfs_end=$(( $rootfs_offset + $rootfs_size ))
- +
- + XIAOMI_RESTORE_ROOTFS2=false
- + xiaomi_flash_images $kernel_offset $kernel_size $rootfs_offset $rootfs_size || {
- + log_err "can't flash factory image"
- + return 1
- + }
- + exit 0
- +}
- +
- +xiaomi_do_revert_stock() {
- + local err
- + local magic
- + local blk blkpos blk_magic offset file_size
- + local kernel_offset
- + local kernel_size=0
- + local rootfs_offset
- + local rootfs_size=0
- +
- + local kernel_mtd=$( find_mtd_index $XIAOMI_KERNEL_PART )
- + if [ -z "$kernel_mtd" ]; then
- + log_err "partition '$XIAOMI_KERNEL_PART' not found"
- + return 1
- + fi
- + log_msg "Forced revert to stock firmware..."
- +
- + for blk in 16 20 24 28 32 36; do
- + blkpos=$( get_uint32_at $blk )
- + [ -z "$blkpos" ] && continue
- + [ $blkpos -lt 48 ] && continue
- + blk_magic=$( get_hexdump_at $blkpos 4 )
- + [ "$blk_magic" != $MAGIC_XIAOMI_BLK ] && continue
- + offset=$(( $blkpos + 8 ))
- + file_size=$( get_uint32_at $offset 4 )
- + [ -z "$file_size" ] && continue
- + [ $file_size -lt 1000000 ] && continue
- + offset=$(( $blkpos + 48 ))
- + magic=$( get_hexdump_at $offset 4 )
- + if [ "$magic" = $MAGIC_UIMAGE ]; then
- + kernel_size=$file_size
- + kernel_offset=$offset
- + fi
- + if [ "$magic" = $MAGIC_UBI -o "$magic" = $MAGIC_HSQS ]; then
- + rootfs_size=$file_size
- + rootfs_offset=$offset
- + fi
- + done
- + if [ $kernel_size -eq 0 ]; then
- + log_err "incorrect stock firmware image (kernel not found)"
- + return 1
- + fi
- + if [ $rootfs_size -eq 0 ]; then
- + log_err "incorrect stock firmware image (rootfs not found)"
- + return 1
- + fi
- +
- + XIAOMI_RESTORE_ROOTFS2=true
- + xiaomi_flash_images $kernel_offset $kernel_size $rootfs_offset $rootfs_size || {
- + log_err "ERROR: can't revert to stock firmware"
- + return 1
- + }
- + exit 0
- +}
- +
- +platform_do_upgrade_xiaomi() {
- + XIAOMI_FW_FILE=$1
- + local stock_rootfs_size=$2
- + local magic
- + local kernel_mtd kernel2_mtd rootfs_mtd
- + local kernel2_part_list part_name
- +
- + XIAOMI_FW_SIZE=$( wc -c "$XIAOMI_FW_FILE" 2> /dev/null | awk '{print $1}' )
- + if [ -z "$XIAOMI_FW_SIZE" ]; then
- + log_err "File '$XIAOMI_FW_FILE' not found!"
- + exit 1
- + fi
- + if [ $XIAOMI_FW_SIZE -lt 1000000 ]; then
- + log_err "file '$XIAOMI_FW_FILE' is incorrect"
- + exit 1
- + fi
- +
- + kernel_mtd=$( find_mtd_index $XIAOMI_KERNEL_PART )
- + if [ -z "$kernel_mtd" ]; then
- + log_err "cannot find mtd partition for '$XIAOMI_KERNEL_PART'"
- + exit 1
- + fi
- + kernel2_part_list=$( echo "$XIAOMI_KERNEL2_NAMES" | sed 's/|/\n/g' )
- + for part_name in $kernel2_part_list; do
- + kernel2_mtd=$( find_mtd_index $part_name )
- + if [ -n "$kernel2_mtd" ]; then
- + XIAOMI_KERNEL2_PART="$part_name"
- + log_msg "Found alt kernel partition '$XIAOMI_KERNEL2_PART'"
- + break
- + fi
- + done
- + rootfs_mtd=$( find_mtd_index $XIAOMI_ROOTFS_PART )
- + if [ -z "$rootfs_mtd" ]; then
- + log_err "cannot find mtd partition for '$XIAOMI_ROOTFS_PART'"
- + exit 1
- + fi
- +
- + magic=$( get_hexdump_at 0 4 )
- +
- + # Flash factory image (uImage header)
- + if [ "$magic" = $MAGIC_UIMAGE ]; then
- + xiaomi_do_factory_upgrade
- + exit $?
- + fi
- +
- + # Revert to stock firmware ("HDR1" header)
- + if [ "$magic" = $MAGIC_XIAOMI_HDR1 ]; then
- + if [ -n "$stock_rootfs_size" ]; then
- + XIAOMI_ROOTFS_PARTSIZE=$stock_rootfs_size
- + fi
- + xiaomi_do_revert_stock
- + exit $?
- + fi
- +
- + magic=$( get_hexdump_at 0 8 )
- + if [ "$magic" != $MAGIC_SYSUPG ]; then
- + log_err "incorrect image for system upgrading!"
- + exit 1
- + fi
- + log_msg "SysUpgrade start..."
- + local tar_file=$XIAOMI_FW_FILE
- + local board_dir=$( tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$' )
- + [ -z "$board_dir" ] && {
- + log_err "board dir not found"
- + exit 1
- + }
- + board_dir=${board_dir%/}
- +
- + local control_len=$( (tar xf $tar_file $board_dir/CONTROL -O | wc -c) 2> /dev/null)
- + if [ $control_len -lt 3 ]; then
- + log_err "incorrect stock firmware image (CONTROL not found)"
- + exit 1
- + fi
- + local kernel_len=$( (tar xf $tar_file $board_dir/kernel -O | wc -c) 2> /dev/null)
- + if [ $kernel_len -lt 1000000 ]; then
- + log_err "incorrect stock firmware image (kernel not found)"
- + exit 1
- + fi
- + local rootfs_len=$( (tar xf $tar_file $board_dir/root -O | wc -c) 2> /dev/null)
- + if [ $rootfs_len -lt 1000000 ]; then
- + log_err "incorrect stock firmware image (rootfs not found)"
- + exit 1
- + fi
- +
- + if [ -n "$XIAOMI_KERNEL2_PART" ]; then
- + tar Oxf $tar_file $board_dir/kernel | mtd -f write - $XIAOMI_KERNEL2_PART && {
- + log_msg "Kernel image flashed to '$XIAOMI_KERNEL2_PART'"
- + } || {
- + log_err "cannot flash partition '$XIAOMI_KERNEL2_PART'"
- + exit 1
- + }
- + fi
- +
- + nand_do_upgrade "$XIAOMI_FW_FILE"
- +}
- diff --git a/target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-r3d.dts b/target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-r3d.dts
- new file mode 100644
- index 0000000000000..fd952d230c5da
- --- /dev/null
- +++ b/target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-r3d.dts
- @@ -0,0 +1,479 @@
- +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
- +
- +#include "qcom-ipq8064-v2.0-smb208.dtsi"
- +
- +#include <dt-bindings/input/input.h>
- +
- +/ {
- + model = "Xiaomi Mi Router HD (R3D)";
- + compatible = "xiaomi,r3d", "qcom,ipq8064";
- +
- + memory@0 {
- + device_type = "memory";
- + reg = <0x42000000 0x1e000000>;
- + };
- +
- + reserved-memory {
- + rsvd@44600000 {
- + reg = <0x44600000 0x200000>; /* IPQ_TZ_APPS_ADDR */
- + no-map;
- + };
- + };
- +
- + aliases {
- + label-mac-device = &gmac1;
- +
- + mdio-gpio0 = &mdio0;
- +
- + led-boot = &led_status_yellow;
- + led-failsafe = &led_status_red;
- + led-running = &led_status_blue;
- + led-upgrade = &led_status_yellow;
- + };
- +
- + chosen {
- + bootargs = "rootfstype=squashfs noinitrd";
- + };
- +
- + keys {
- + compatible = "gpio-keys";
- + pinctrl-0 = <&button_pins>;
- + pinctrl-names = "default";
- +
- + reset {
- + label = "reset";
- + gpios = <&qcom_pinmux 16 GPIO_ACTIVE_LOW>;
- + linux,code = <KEY_RESTART>;
- + debounce-interval = <60>;
- + wakeup-source;
- + };
- +
- + power {
- + label = "power"; /* Labeled POWER on the device, but using for sleep mode */
- + gpios = <&qcom_pinmux 68 GPIO_ACTIVE_LOW>;
- + linux,code = <KEY_POWER>;
- + debounce-interval = <60>;
- + wakeup-source;
- + };
- + };
- +
- + leds {
- + compatible = "gpio-leds";
- + pinctrl-0 = <&led_pins>;
- + pinctrl-names = "default";
- +
- + led_status_red: led_status_red {
- + label = "red:status";
- + gpios = <&qcom_pinmux 7 GPIO_ACTIVE_HIGH>;
- + default-state = "keep";
- + };
- +
- + led_status_blue: led_status_blue {
- + label = "blue:status";
- + gpios = <&qcom_pinmux 8 GPIO_ACTIVE_HIGH>;
- + default-state = "keep";
- + };
- +
- + led_status_yellow: led_status_yellow {
- + label = "yellow:status";
- + gpios = <&qcom_pinmux 9 GPIO_ACTIVE_HIGH>;
- + default-state = "keep";
- + };
- + };
- +
- + i2c_gpio_0 { // GSBI1
- + compatible = "i2c-gpio";
- + #address-cells = <1>;
- + #size-cells = <0>;
- + pinctrl-0 = <&i2c1_pins>;
- + pinctrl-names = "default";
- + sda-gpios = <&qcom_pinmux 53 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- + scl-gpios = <&qcom_pinmux 54 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- + i2c-gpio,delay-us = <5>;
- +
- + emc2301@2f {
- + compatible = "smsc,emc2301";
- + reg = <0x2f>;
- + #address-cells = <1>;
- + #size-cells = <0>;
- +
- + fan@0 {
- + reg = <0>;
- + pwm-output-mode = <1>;
- + };
- + };
- + };
- +
- + i2c_gpio_1 { // GSBI2
- + compatible = "i2c-gpio";
- + #address-cells = <1>;
- + #size-cells = <0>;
- + pinctrl-0 = <&i2c2_pins>;
- + pinctrl-names = "default";
- + sda-gpios = <&qcom_pinmux 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- + scl-gpios = <&qcom_pinmux 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- + i2c-gpio,delay-us = <5>;
- +
- + tmp75@48 {
- + compatible = "ti,tmp75";
- + reg = <0x48>;
- + #address-cells = <1>;
- + #size-cells = <0>;
- + #thermal-sensor-cells = <0>;
- + status = "okay";
- + };
- + };
- +};
- +
- +// https://github.com/openwrt/openwrt/commit/622ce713ca246aa465bf28d2a743f96999085ea2
- +// https://github.com/openwrt/openwrt/commit/2336c2dbb1929837f7e42d4315c8073342a5b46b
- +// https://forum.openwrt.org/t/failed-to-startup-an-ipq806x-router-on-kernel-5-4/60775/41
- +&CPU_SPC {
- + status = "disabled";
- +};
- +
- +&adm_dma {
- + status = "okay";
- +};
- +
- +&qcom_pinmux {
- + i2c1_pins: i2c1_pins { // GSBI1 - EMC2301
- + mux {
- + pins = "gpio53", "gpio54";
- + function = "gsbi1";
- + drive-strength = <12>;
- + bias-none;
- + input;
- + };
- + };
- +
- + i2c2_pins: i2c2_pins { // GSBI2 - TMP75
- + mux {
- + pins = "gpio24", "gpio25";
- + function = "gsbi2";
- + drive-strength = <12>;
- + bias-none;
- + input;
- + };
- + };
- +
- + button_pins: button_pins {
- + mux {
- + pins = "gpio16", "gpio68";
- + function = "gpio";
- + drive-strength = <2>;
- + bias-pull-up;
- + };
- + };
- +
- + led_pins: led_pins {
- + mux {
- + pins = "gpio7", "gpio8", "gpio9";
- + function = "gpio";
- + drive-strength = <2>;
- + bias-pull-up;
- + };
- + };
- +
- + usb_pwr_en_pins: usb_pwr_en_pins {
- + mux {
- + pins = "gpio56";
- + function = "gpio";
- + drive-strength = <12>;
- + bias-pull-up;
- + output-high;
- + };
- + };
- +};
- +
- +&sata_phy {
- + status = "okay";
- +};
- +
- +&sata {
- + status = "okay";
- +};
- +
- +&hs_phy_0 {
- + status = "okay";
- +};
- +
- +&ss_phy_0 {
- + status = "okay";
- +};
- +
- +&usb3_0 {
- + status = "okay";
- +};
- +
- +&hs_phy_1 {
- + status = "okay";
- +};
- +
- +&ss_phy_1 {
- + status = "okay";
- +};
- +
- +&usb3_1 {
- + status = "okay";
- + pinctrl-0 = <&usb_pwr_en_pins>;
- + pinctrl-names = "default";
- +};
- +
- +&pcie0 {
- + status = "okay";
- + reset-gpio = <&qcom_pinmux 3 GPIO_ACTIVE_LOW>;
- + pinctrl-0 = <&pcie0_pins>;
- + pinctrl-names = "default";
- +
- + bridge@0,0 {
- + reg = <0x00000000 0 0 0 0>;
- + #address-cells = <3>;
- + #size-cells = <2>;
- + ranges;
- +
- + wifi@1,0 {
- + compatible = "pci168c,0040";
- + reg = <0x00010000 0 0 0 0>;
- +
- + nvmem-cells = <&macaddr_art_1006>, <&precal_art_1000>;
- + nvmem-cell-names = "mac-address", "pre-calibration";
- + };
- + };
- +};
- +
- +&pcie1 {
- + status = "okay";
- + reset-gpio = <&qcom_pinmux 48 GPIO_ACTIVE_LOW>;
- + pinctrl-0 = <&pcie1_pins>;
- + pinctrl-names = "default";
- + max-link-speed = <1>;
- +
- + bridge@0,0 {
- + reg = <0x00000000 0 0 0 0>;
- + #address-cells = <3>;
- + #size-cells = <2>;
- + ranges;
- +
- + wifi@1,0 {
- + compatible = "pci168c,0040";
- + reg = <0x00010000 0 0 0 0>;
- +
- + nvmem-cells = <&macaddr_art_5006>, <&precal_art_5000>;
- + nvmem-cell-names = "mac-address", "pre-calibration";
- + };
- + };
- +};
- +
- +&nand {
- + status = "okay";
- +
- + pinctrl-0 = <&nand_pins>;
- + pinctrl-names = "default";
- +
- + nand@0 {
- + reg = <0>;
- + compatible = "qcom,nandcs";
- +
- + nand-bus-width = <8>;
- + nand-ecc-strength = <4>;
- + nand-ecc-step-size = <512>;
- +
- + nand-is-boot-medium;
- + qcom,boot-partitions = <0 0xf0000000>;
- +
- + partitions {
- + compatible = "fixed-partitions";
- + #address-cells = <1>;
- + #size-cells = <1>;
- +
- + partition@0 {
- + label = "SBL1";
- + reg = <0x0 0x40000>;
- + read-only;
- + };
- +
- + partition@40000 {
- + label = "MIBIB";
- + reg = <0x40000 0x80000>;
- + read-only;
- + };
- +
- + partition@c0000 {
- + label = "SBL2";
- + reg = <0xc0000 0x80000>;
- + read-only;
- + };
- +
- + partition@140000 {
- + label = "SBL3";
- + reg = <0x140000 0x80000>;
- + read-only;
- + };
- +
- + partition@1c0000 {
- + label = "DDRCONFIG";
- + reg = <0x1c0000 0x80000>;
- + read-only;
- + };
- +
- + partition@240000 {
- + label = "SSD";
- + reg = <0x240000 0x80000>;
- + read-only;
- + };
- +
- + partition@2c0000 {
- + label = "TZ";
- + reg = <0x2c0000 0x80000>;
- + read-only;
- + };
- +
- + partition@340000 {
- + label = "RPM";
- + reg = <0x340000 0x80000>;
- + read-only;
- + };
- +
- + partition@3c0000 {
- + label = "APPSBL";
- + reg = <0x3c0000 0x100000>;
- + read-only;
- + };
- +
- + partition@4c0000 {
- + label = "APPSBLENV";
- + reg = <0x4c0000 0x80000>;
- + };
- +
- + art: partition@540000 {
- + label = "ART";
- + reg = <0x540000 0x80000>;
- + read-only;
- +
- + compatible = "nvmem-cells";
- + #address-cells = <1>;
- + #size-cells = <1>;
- +
- + macaddr_art_0: macaddr@0 { // WAN (label)
- + reg = <0x0 0x6>;
- + };
- + macaddr_art_6: macaddr@6 { // LAN
- + reg = <0x6 0x6>;
- + };
- + macaddr_art_1006: macaddr@1006 { // WiFi 2g
- + reg = <0x1006 0x6>;
- + };
- + macaddr_art_5006: macaddr@5006 { // WiFi 5g
- + reg = <0x5006 0x6>;
- + };
- + precal_art_1000: precal@1000 {
- + reg = <0x1000 0x2f20>;
- + };
- + precal_art_5000: precal@5000 {
- + reg = <0x5000 0x2f20>;
- + };
- + };
- +
- + partition@5c0000 {
- + label = "BOOTCONFIG";
- + reg = <0x5c0000 0x40000>;
- + read-only;
- + };
- +
- + partition@600000 {
- + label = "bdata";
- + reg = <0x600000 0x80000>;
- + };
- +
- + partition@680000 {
- + label = "crash";
- + reg = <0x680000 0x80000>;
- + read-only;
- + };
- +
- + partition@700000 {
- + label = "crash_syslog";
- + reg = <0x700000 0x80000>;
- + read-only;
- + };
- +
- + partition@780000 {
- + label = "rsvd";
- + reg = <0x780000 0x80000>;
- + read-only;
- + };
- +
- + /* Stock U-Boot support Dual Boot */
- + partition@800000 {
- + label = "kernel_dup";
- + reg = <0x800000 0x400000>;
- + };
- +
- + partition@c00000 {
- + label = "kernel";
- + reg = <0xc00000 0x400000>;
- + };
- +
- + partition@1000000 {
- + label = "ubi";
- + reg = <0x1000000 0xf000000>;
- + };
- + };
- + };
- +};
- +
- +&mdio0 {
- + status = "okay";
- +
- + pinctrl-0 = <&mdio0_pins>;
- + pinctrl-names = "default";
- +
- + phy0: ethernet-phy@0 {
- + reg = <0>;
- + qca,ar8327-initvals = <
- + 0x04 0x07600000 /* PAD0_MODE */
- + 0x08 0x01000000 /* PAD5_MODE */
- + 0x0c 0x00000080 /* PAD6_MODE */
- + 0x7c 0x0000004e /* PORT0_STATUS */
- + 0x94 0x0000004e /* PORT6_STATUS */
- + 0xe0 0xc74164de /* SGMII_CTRL */
- + 0xe4 0x0006a545 /* MAC_POWER_SEL */
- + >;
- + };
- +
- + phy4: ethernet-phy@4 {
- + reg = <4>;
- + };
- +};
- +
- +&gmac1 {
- + status = "okay";
- + phy-mode = "rgmii";
- + qcom,id = <1>;
- +
- + pinctrl-0 = <&rgmii2_pins>;
- + pinctrl-names = "default";
- +
- + nvmem-cells = <&macaddr_art_0>;
- + nvmem-cell-names = "mac-address";
- +
- + fixed-link {
- + speed = <1000>;
- + full-duplex;
- + };
- +};
- +
- +&gmac2 {
- + status = "okay";
- + phy-mode = "sgmii";
- + qcom,id = <2>;
- +
- + nvmem-cells = <&macaddr_art_6>;
- + nvmem-cell-names = "mac-address";
- +
- + fixed-link {
- + speed = <1000>;
- + full-duplex;
- + };
- +};
- diff --git a/target/linux/ipq806x/image/generic.mk b/target/linux/ipq806x/image/generic.mk
- index aac0a2c8fadfd..b437706cd445e 100644
- --- a/target/linux/ipq806x/image/generic.mk
- +++ b/target/linux/ipq806x/image/generic.mk
- @@ -471,6 +471,23 @@ define Device/ubnt_unifi-ac-hd
- endef
- TARGET_DEVICES += ubnt_unifi-ac-hd
-
- +define Device/xiaomi_r3d
- + $(call Device/LegacyImage)
- + DEVICE_VENDOR := Xiaomi
- + DEVICE_MODEL := R3D
- + SOC := qcom-ipq8064
- + BLOCKSIZE := 128k
- + PAGESIZE := 2048
- + KERNEL_SIZE := 4096k
- + IMAGE_SIZE := 86016k
- + UBINIZE_OPTS := -E 5
- + IMAGES := factory.bin sysupgrade.bin
- + IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi | pad-to $$$$(BLOCKSIZE) | check-size
- + DEVICE_PACKAGES := kmod-i2c-gpio kmod-hwmon-lm75 kmod-hwmon-emc2305 hwmon-drivetemp \
- + kmod-usb-storage-uas ath10k-firmware-qca9984-ct ath10k-firmware-qca99x0-ct
- +endef
- +TARGET_DEVICES += xiaomi_r3d
- +
- define Device/zyxel_nbg6817
- DEVICE_VENDOR := ZyXEL
- DEVICE_MODEL := NBG6817
|