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
* STOR: 256MB NAND (Macronix MX30UF2G18AC-TI)
* ETH:  1x WAN 10/100/1000, 3x LAN 10/100/1000
* 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 |

Partition layout and boot:

Stock Xiaomi firmware has the MTD split into (among others)

- kernel0 (@0x0800000)
- kernel1 (@0x0c00000)
- rootfs0 (@0x1000000)
- rootfs1 (@0x3800000)
- overlay (@0x6000000)

Xiaomi uboot expects to find kernels at 0x800000 & 0xc00000
referred to as system 1 & system 2 respectively.
a kernel is considered suitable for handing control over
if its linux magic number exists & uImage CRC are correct.
If either of those conditions fail, a matching sys'n'_fail flag
is set in uboot env & a restart performed in the hope that the
alternate kernel is okay.
If neither kernel checksums ok and both are marked failed, system 2
is booted anyway.

Note uboot's tftp flash install writes the transferred
image to both kernel partitions.

Methods for getting SSH access:
1) https://github.com/acecilia/OpenWRTInvasion
2) https://github.com/openwrt-xiaomi/xmir-patcher

Installation:

The installation file for OpenWRT is a *squashfs-factory.bin file that
contains the kernel and a ubi partition. This is flashed as follows:

nvram flag_boot_success=1
nvram flag_boot_rootfs=1
nvram flag_last_success=1
nvram flag_try_sys1_failed=0
nvram flag_try_sys2_failed=0
nvram commit
dd if=factory.bin bs=1M count=4 | mtd write - kernel0
dd if=factory.bin bs=1M count=4 | mtd write - kernel1
dd if=factory.bin bs=1M skip=4  | mtd write - rootfs0
reboot

Reverting to stock:

Download facinstall.ipk from link
https://github.com/openwrt-xiaomi/facinstall/releases/latest
and install its.
Install miwifi_r3d_firmware_XXXXX.bin image via LuCI interface.

Signed-off-by: Oleg S <remittor@gmail.com>
This commit is contained in:
Oleg S 2024-09-09 12:00:21 +03:00
parent 2cfcb90882
commit 8d4cd1aa49
7 changed files with 625 additions and 2 deletions

View File

@ -56,6 +56,10 @@ qcom,ipq8064-ap148|\
qcom,ipq8064-db149)
ubootenv_add_uci_config $(ubootenv_mtdinfo)
;;
xiaomi,r3d)
ubootenv_add_uci_config "/dev/mtd9" "0x0" "0x10000" "0x20000"
ubootenv_add_uci_sys_config "/dev/mtd12" "0x0" "0x10000" "0x20000"
;;
ubnt,unifi-ac-hd|\
zyxel,nbg6817)
ubootenv_add_uci_config "/dev/mtdblock9" "0x0" "0x10000" "0x10000"
@ -63,6 +67,6 @@ zyxel,nbg6817)
esac
config_load ubootenv
config_foreach ubootenv_add_app_config ubootenv
config_foreach ubootenv_add_app_config
exit 0

View File

@ -67,6 +67,13 @@ ipq806x_setup_interfaces()
meraki,mr52)
ucidef_set_interfaces_lan_wan "eth0" "eth1"
;;
xiaomi,r3d)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" "wan"
ucidef_set_network_device_conduit "lan1" "eth1"
ucidef_set_network_device_conduit "lan2" "eth1"
ucidef_set_network_device_conduit "lan3" "eth1"
ucidef_set_network_device_conduit "wan" "eth0"
;;
*)
echo "Unsupported hardware. Network interfaces not intialized"
;;

View File

@ -19,5 +19,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 )
[ -z "$bootdelay" -o "$bootdelay" == "0" ] && fw_setenv bootdelay 3
local uart_en=$( fw_printenv uart_en | cut -d = -f 2 )
[ "$uart_en" != "1" ] && fw_setenv uart_en 1
;;
esac
}

View File

@ -0,0 +1,20 @@
#!/bin/sh /etc/rc.common
START=98
boot() {
local path_to_hwmon
# configuring onboard temp/fan controller to run the fan on its own
# for more information, please read https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
case $(board_name) in
xiaomi,r3d)
path_to_hwmon="$( grep -l emc230 /sys/class/hwmon/hwmon*/name )"
if [ -n "$path_to_hwmon" ]; then
path_to_hwmon=$( dirname "$path_to_hwmon" 2>/dev/null )
# Set FAN speed to 80%
echo "204" > "$path_to_hwmon/pwm1"
fi
;;
esac
}

View File

@ -23,7 +23,8 @@ platform_do_upgrade() {
netgear,xr500 |\
nokia,ac400i |\
qcom,ipq8064-ap148 |\
qcom,ipq8064-ap161)
qcom,ipq8064-ap161 |\
xiaomi,r3d)
nand_do_upgrade "$1"
;;
asrock,g10)

View File

@ -0,0 +1,562 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include "qcom-ipq8064-v2.0-smb208.dtsi"
#include <dt-bindings/input/input.h>
#include <dt-bindings/leds/common.h>
/ {
model = "Xiaomi Mi Router HD (R3D)";
compatible = "xiaomi,r3d", "qcom,ipq8064";
memory@0 {
device_type = "memory";
reg = <0x42000000 0x1e000000>;
};
reserved-memory {
ramoops@42100000 {
compatible = "ramoops";
reg = <0x42100000 0x40000>;
record-size = <0x4000>;
console-size = <0x4000>;
ftrace-size = <0x4000>;
pmsg-size = <0x4000>;
};
};
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";
};
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";
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 {
function = LED_FUNCTION_STATUS;
color = <LED_COLOR_ID_RED>;
gpios = <&qcom_pinmux 7 GPIO_ACTIVE_HIGH>;
};
led_status_blue: led_status_blue {
function = LED_FUNCTION_STATUS;
color = <LED_COLOR_ID_BLUE>;
gpios = <&qcom_pinmux 8 GPIO_ACTIVE_HIGH>;
};
led_status_yellow: led_status_yellow {
function = LED_FUNCTION_STATUS;
color = <LED_COLOR_ID_YELLOW>;
gpios = <&qcom_pinmux 9 GPIO_ACTIVE_HIGH>;
};
};
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>;
fan@2f {
compatible = "microchip,emc2305";
reg = <0x2f>;
emc2305,pwm-channel = <0>;
emc2305,pwm-min = <0>;
emc2305,pwm-max = <255>;
};
};
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>;
temp-sensor@48 {
compatible = "ti,tmp75";
reg = <0x48>;
#thermal-sensor-cells = <0>;
status = "okay";
};
};
reg_usb_vbus: regulator-usb-vbus {
compatible = "regulator-fixed";
regulator-name = "USB_VBUS";
//pinctrl-names = "default";
//pinctrl-0 = <&pinctrl_usbhost>;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
regulator-boot-on;
regulator-always-on;
enable-active-high;
gpios = <&qcom_pinmux 56 GPIO_ACTIVE_HIGH>;
};
output-usb-power {
compatible = "regulator-output";
vout-supply = <&reg_usb_vbus>;
};
};
&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;
};
};
};
&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";
vbus-supply = <&reg_usb_vbus>;
};
&pcie0 {
status = "okay";
reset-gpios = <&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,0046";
reg = <0x00010000 0 0 0 0>;
nvmem-cells = <&precal_art_1000>, <&macaddr_art_1006>;
nvmem-cell-names = "pre-calibration", "mac-address";
};
};
};
&pcie1 {
status = "okay";
reset-gpios = <&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 = <&precal_art_5000>, <&macaddr_art_5006>;
nvmem-cell-names = "pre-calibration", "mac-address";
};
};
};
&nand {
status = "okay";
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;
nvmem-layout {
compatible = "fixed-layout";
#address-cells = <1>;
#size-cells = <1>;
macaddr_art_0: macaddr@0 { /* WAN (label) */
compatible = "mac-base";
reg = <0x0 0x6>;
#nvmem-cell-cells = <1>;
};
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;
};
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";
switch@10 {
compatible = "qca,qca8337";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x10>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
label = "cpu";
ethernet = <&gmac1>;
phy-mode = "rgmii";
tx-internal-delay-ps = <1000>;
rx-internal-delay-ps = <1000>;
fixed-link {
speed = <1000>;
full-duplex;
};
};
port@1 {
reg = <1>;
label = "lan3";
phy-mode = "internal";
phy-handle = <&phy_port1>;
};
port@2 {
reg = <2>;
label = "lan2";
phy-mode = "internal";
phy-handle = <&phy_port2>;
};
port@3 {
reg = <3>;
label = "lan1";
phy-mode = "internal";
phy-handle = <&phy_port3>;
};
port@5 {
reg = <5>;
label = "wan";
phy-mode = "internal";
phy-handle = <&phy_port5>;
};
port@6 {
reg = <6>;
label = "cpu";
ethernet = <&gmac2>;
phy-mode = "sgmii";
qca,sgmii-enable-pll;
fixed-link {
speed = <1000>;
full-duplex;
};
};
};
mdio {
#address-cells = <1>;
#size-cells = <0>;
phy_port1: phy@0 {
reg = <0>;
};
phy_port2: phy@1 {
reg = <1>;
};
phy_port3: phy@2 {
reg = <2>;
};
phy_port4: phy@3 {
reg = <3>;
};
phy_port5: 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 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 0>;
nvmem-cell-names = "mac-address";
fixed-link {
speed = <1000>;
full-duplex;
};
};

View File

@ -576,6 +576,27 @@ 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 := Mi Router HD (R3D)
SOC := qcom-ipq8064
BLOCKSIZE := 128k
PAGESIZE := 2048
KERNEL_SIZE := 4096k
IMAGE_SIZE := 86016k
BOARD_NAME := r3d
UBINIZE_OPTS := -E 5
IMAGES += factory.bin
IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | \
append-ubi | pad-to $$$$(BLOCKSIZE) | check-size
DEVICE_PACKAGES := kmod-i2c-gpio kmod-thermal kmod-hwmon-lm75 \
kmod-hwmon-emc2305 hwmon-drivetemp kmod-usb-storage-uas \
kmod-ramoops \
ath10k-firmware-qca9984-ct ath10k-firmware-qca99x0-ct
endef
TARGET_DEVICES += xiaomi_r3d
define Device/zyxel_nbg6817
$(Device/dsa-migration)
DEVICE_VENDOR := Zyxel