From dc27d768f8dc851fbe751488073114060a67dfee Mon Sep 17 00:00:00 2001 From: George Moussalem Date: Mon, 7 Oct 2024 16:09:40 +0400 Subject: [PATCH] qualcommax: ipq50xx: add support for Linksys MX2000 and MX5500 Add support for Linksys MX2000 (Atlas 6) and MX5500 (Atlas 6 Pro). These devices are completely identical except for the secondary wifi chip used for 5Ghz: QCN6102 is used on MX2000 while QCN9024 is used on MX5500 Speficiations: * SoC: Qualcomm IPQ5018 (64-bit dual-core ARM Cortex-A53 @ 1.0Ghz) * Memory: Winbond W634GU6NB-11 (512 MiB DDR3-933) * Serial Port: 3v3 TTL 115200n8 * Wi-Fi: IPQ5018 (2x2 2.4 Ghz 802.11b/g/n/ax) * Wi-Fi: MX2000: QCN6102 (2x2:2 5 Ghz 802.11an/ac/ax) MX5500: QCN9024 (4x4:4 5 Ghz 802.11an/ac/ax) * Ethernet: IPQ5018 integrated virtual switch connected to an external QCA8337 switch (4 Ports 10/100/1000 GBASE-T) * Flash: Macronix MX35UF2GE4AD (256 MiB) * LEDs: 1x multi-color PWM LED * Buttons: 1x WPS (GPIO 27 Active Low) 1x Reset (GPIO 28 Acive Low) Flash instructions (in case of MX2000, else replace with MX5500 images): 1. On OEM firmware, login to the device (typically at http://192.168.1.1) and click 'CA' in the bottom right corner -> Connectivity -> Manual Upgrade. Alternatively, browse to http:///fwupdate.html. Upgrade firmware using openwrt-qualcommax-ipq50xx-linksys_mx2000-squashfs-factory.bin image. Optionally install on second partition, after first boot check actual partition: fw_printenv -n boot_part and install firmware on second partition using command in case of 2: mtd -r -e kernel -n write openwrt-qualcommax-ipq50xx-linksys_mx2000-squashfs-factory.bin kernel and in case of 1: mtd -r -e alt_kernel -n write openwrt-qualcommax-ipq50xx-linksys_mx2000-squashfs-factory.bin alt_kernel 2. Installation using serial connection from OEM firmware (default login: root, password: admin): fw_printenv -n boot_part In case of 2: flash_erase /dev/mtd12 0 0 nandwrite -p /dev/mtd12 openwrt-qualcommax-ipq50xx-linksys_mx2000-squashfs-factory.bin or in case of 1: flash_erase /dev/mtd14 0 0 nandwrite -p /dev/mtd14 openwrt-qualcommax-ipq50xx-linksys_mx2000-squashfs-factory.bin After first boot install firmware on second partition: mtd -r -e kernel -n write openwrt-qualcommax-ipq50xx-linksys_mx2000-squashfs-factory.bin kernel or: mtd -r -e alt_kernel -n write openwrt-qualcommax-ipq50xx-linksys_mx2000-squashfs-factory.bin alt_kernel 3. Back to the OEM firmware. Download firmware from OEM website: MX2000: https://support.linksys.com/kb/article/585-en/ MX5500: https://support.linksys.com/kb/article/587-en/ From serial or SSH: fw_printenv boot_part in case of 1: mtd -r -e alt_kernel -n write FW_MX2000_1.1.7.210469_prod.img alt_kernel else in case of 2: mtd -r -e kernel -n write FW_MX2000_1.1.7.210469_prod.img kernel Signed-off-by: George Moussalem --- package/base-files/files/sbin/sysupgrade | 4 + .../uboot-envtools/files/qualcommax_ipq50xx | 22 + package/firmware/ipq-wifi/Makefile | 4 + .../ipq-wifi/src/board-linksys_mx2000.ipq5018 | Bin 0 -> 131180 bytes .../ipq-wifi/src/board-linksys_mx2000.qcn6122 | Bin 0 -> 131180 bytes .../ipq-wifi/src/board-linksys_mx5500.ipq5018 | Bin 0 -> 131180 bytes .../ipq-wifi/src/board-linksys_mx5500.qcn9074 | Bin 0 -> 131180 bytes .../boot/dts/qcom/ipq5018-mx-atlas6.dtsi | 554 ++++++++++++++++++ .../arm64/boot/dts/qcom/ipq5018-mx2000.dts | 152 +++++ .../arm64/boot/dts/qcom/ipq5018-mx5500.dts | 102 ++++ target/linux/qualcommax/image/ipq50xx.mk | 31 + .../ipq50xx/base-files/etc/board.d/02_network | 45 ++ .../etc/hotplug.d/firmware/11-ath11k-caldata | 47 ++ .../ipq50xx/base-files/etc/init.d/bootcount | 12 + .../ipq50xx/base-files/lib/upgrade/linksys.sh | 125 ++++ .../base-files/lib/upgrade/platform.sh | 32 + 16 files changed, 1130 insertions(+) create mode 100644 package/boot/uboot-envtools/files/qualcommax_ipq50xx create mode 100644 package/firmware/ipq-wifi/src/board-linksys_mx2000.ipq5018 create mode 100644 package/firmware/ipq-wifi/src/board-linksys_mx2000.qcn6122 create mode 100644 package/firmware/ipq-wifi/src/board-linksys_mx5500.ipq5018 create mode 100644 package/firmware/ipq-wifi/src/board-linksys_mx5500.qcn9074 create mode 100644 target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx-atlas6.dtsi create mode 100644 target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx2000.dts create mode 100644 target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx5500.dts create mode 100644 target/linux/qualcommax/ipq50xx/base-files/etc/board.d/02_network create mode 100644 target/linux/qualcommax/ipq50xx/base-files/etc/hotplug.d/firmware/11-ath11k-caldata create mode 100755 target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount create mode 100644 target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/linksys.sh create mode 100644 target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh diff --git a/package/base-files/files/sbin/sysupgrade b/package/base-files/files/sbin/sysupgrade index 611d8830bfd..c91cd615374 100755 --- a/package/base-files/files/sbin/sysupgrade +++ b/package/base-files/files/sbin/sysupgrade @@ -20,6 +20,7 @@ CONF_IMAGE= CONF_BACKUP_LIST=0 CONF_BACKUP= CONF_RESTORE= +CURR_PARTITION=0 NEED_IMAGE= HELP=0 TEST=0 @@ -50,6 +51,7 @@ while [ -n "$1" ]; do -r|--restore-backup) CONF_RESTORE="$2" NEED_IMAGE=1; shift;; -l|--list-backup) CONF_BACKUP_LIST=1;; -f) CONF_IMAGE="$2"; shift;; + -s) CURR_PARTITION=1;; -F|--force) export FORCE=1;; -T|--test) TEST=1;; -h|--help) HELP=1; break;; @@ -79,6 +81,7 @@ upgrade-option: -p do not attempt to restore the partition table after flash. -k include in backup a list of current installed packages at $INSTALLED_PACKAGES + -s stay on current partition (for dual firmware devices) -T | --test Verify image and config .tar.gz but do not actually flash. -F | --force @@ -416,6 +419,7 @@ else json_add_string command "$COMMAND" json_add_object options json_add_int save_partitions "$SAVE_PARTITIONS" + [ $CURR_PARTITION -eq 1 ] && json_add_boolean curr_partition 1 json_close_object ubus call system sysupgrade "$(json_dump)" diff --git a/package/boot/uboot-envtools/files/qualcommax_ipq50xx b/package/boot/uboot-envtools/files/qualcommax_ipq50xx new file mode 100644 index 00000000000..97b01df0399 --- /dev/null +++ b/package/boot/uboot-envtools/files/qualcommax_ipq50xx @@ -0,0 +1,22 @@ +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/uboot-envtools.sh +. /lib/functions.sh + +board=$(board_name) + +case "$board" in +linksys,mx2000|\ +linksys,mx5500) + idx="$(find_mtd_index u_env)" + [ -n "$idx" ] && \ + ubootenv_add_uci_config "/dev/mtd$idx" "0x0" "0x40000" "0x20000" "2" + ;; +esac + +config_load ubootenv +config_foreach ubootenv_add_app_config + +exit 0 diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile index c0c86502196..1f2ed253ede 100644 --- a/package/firmware/ipq-wifi/Makefile +++ b/package/firmware/ipq-wifi/Makefile @@ -37,8 +37,10 @@ ALLWIFIBOARDS:= \ dynalink_dl-wrx36 \ edgecore_eap102 \ edimax_cax1800 \ + linksys_mx2000 \ linksys_mx4200 \ linksys_mx5300 \ + linksys_mx5500 \ linksys_mx8500 \ linksys_whw03 \ netgear_lbr20 \ @@ -167,8 +169,10 @@ $(eval $(call generate-ipq-wifi-package,compex_wpq873,Compex WPQ-873)) $(eval $(call generate-ipq-wifi-package,dynalink_dl-wrx36,Dynalink DL-WRX36)) $(eval $(call generate-ipq-wifi-package,edgecore_eap102,Edgecore EAP102)) $(eval $(call generate-ipq-wifi-package,edimax_cax1800,Edimax CAX1800)) +$(eval $(call generate-ipq-wifi-package,linksys_mx2000,Linksys MX2000)) $(eval $(call generate-ipq-wifi-package,linksys_mx4200,Linksys MX4200)) $(eval $(call generate-ipq-wifi-package,linksys_mx5300,Linksys MX5300)) +$(eval $(call generate-ipq-wifi-package,linksys_mx5500,Linksys MX5500)) $(eval $(call generate-ipq-wifi-package,linksys_mx8500,Linksys MX8500)) $(eval $(call generate-ipq-wifi-package,linksys_whw03,Linksys WHW03)) $(eval $(call generate-ipq-wifi-package,netgear_lbr20,Netgear LBR20)) diff --git a/package/firmware/ipq-wifi/src/board-linksys_mx2000.ipq5018 b/package/firmware/ipq-wifi/src/board-linksys_mx2000.ipq5018 new file mode 100644 index 0000000000000000000000000000000000000000..3425c9cea18eb4871c06f957825cfeb7b10101f3 GIT binary patch literal 131180 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 HMBx7eQph>+ literal 0 HcmV?d00001 diff --git a/package/firmware/ipq-wifi/src/board-linksys_mx5500.ipq5018 b/package/firmware/ipq-wifi/src/board-linksys_mx5500.ipq5018 new file mode 100644 index 0000000000000000000000000000000000000000..abaf8b6fbfdd6e9b016c1ac2de9be2ff6b924407 GIT binary patch literal 131180 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 literal 0 HcmV?d00001 diff --git a/package/firmware/ipq-wifi/src/board-linksys_mx5500.qcn9074 b/package/firmware/ipq-wifi/src/board-linksys_mx5500.qcn9074 new file mode 100644 index 0000000000000000000000000000000000000000..7ff8e3d09bfbf3d98cf6be59843570f3692aa4cf GIT binary patch literal 131180 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 literal 0 HcmV?d00001 diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx-atlas6.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx-atlas6.dtsi new file mode 100644 index 00000000000..62076e10772 --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx-atlas6.dtsi @@ -0,0 +1,554 @@ +#include "ipq5018.dtsi" +#include "ipq5018-ess.dtsi" + +#include +#include +#include + +/ { + + aliases { + ethernet0 = &dp1; + ethernet1 = &dp2; + led-boot = &led_system_blue; + led-failsafe = &led_system_red; + led-running = &led_system_blue; + led-upgrade = &led_system_red; + serial0 = &blsp1_uart1; + }; + + chosen { + bootargs-append = " root=/dev/ubiblock0_0 coherent_pool=2M"; + stdout-path = "serial0:115200n8"; + }; + + keys { + compatible = "gpio-keys"; + pinctrl-0 = <&button_pins>; + pinctrl-names = "default"; + + wps-button { + label = "wps"; + gpios = <&tlmm 27 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + reset-button { + label = "reset"; + gpios = <&tlmm 28 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + leds { + compatible = "pwm-leds"; + + led_system_red: red { + label = "red:system"; + pwms = <&pwm 3 1250000>; + max-brightness = <255>; + }; + + green { + label = "green:system"; + pwms = <&pwm 0 1250000>; + max-brightness = <255>; + }; + + led_system_blue: blue { + label = "blue:system"; + pwms = <&pwm 1 1250000>; + max-brightness = <255>; + //linux,default-trigger = "default-on"; + }; + }; + + reserved-memory { + tz_appps@4a400000 { + no-map; + reg = <0x0 0x4a400000 0x0 0x400000>; + }; + + q6_mem_regions: q6_mem_regions@4b000000 { + no-map; + reg = <0x0 0x4b000000 0x0 0x3000000>; + }; + + /* from stock DTS: + q6_code_data: q6_code_data@4b000000 { + no-map; + reg = <0x0 0x4b000000 0x0 0x60000>; + }; + + q6_ipq5018_data: q6_ipq5018_data@4c400000 { + no-map; + reg = <0x0 0x4c400000 0x0 0xe00000>; + }; + + q6_m3_region: m3_dump@4d200000 { + no-map; + reg = <0x0 0x4d200000 0x0 0x100000>; + }; + + q6_etr_region: q6_etr_dump@4d300000 { + no-map; + reg = <0x0 0x4d300000 0x0 0x100000>; + }; + + q6_caldb_region: q6_caldb_region@4d400000 { + no-map; + reg = <0x0 0x4d400000 0x0 0x200000>; + }; + + q6_qcn6122_data1: q6_qcn6122_data1@4d600000 { + no-map; + reg = <0x0 0x4d600000 0x0 0x1000000>; + }; + + q6_qcn6122_m3_1: q6_qcn6122_m3_1@4e600000 { + no-map; + reg = <0x0 0x4e600000 0x0 0x100000>; + }; + + q6_qcn6122_etr_1: q6_qcn6122_etr_1@4e700000 { + no-map; + reg = <0x0 0x4e700000 0x0 0x100000>; + }; + + q6_qcn6122_caldb_1: q6_qcn6122_caldb_1@4e800000 { + no-map; + reg = <0x0 0x4e800000 0x0 0x500000>; + }; + + q6_qcn6122_data2: q6_qcn6122_data20@4ed00000 { + no-map; + reg = <0x0 0x4ed00000 0x0 0x1000000>; + }; + + q6_qcn6122_m3_2: q6_qcn6122_m3_2@4fd00000 { + no-map; + reg = <0x0 0x4fd00000 0x0 0x100000>; + }; + + q6_qcn6122_etr_2: q6_qcn6122_etr_2@4fe00000 { + no-map; + reg = <0x0 0x4fe00000 0x0 0x100000>; + }; + + q6_qcn6122_caldb_2: q6_qcn6122_caldb_2@4ff00000 { + no-map; + reg = <0x0 0x4ff00000 0x0 0x500000>; + }; + */ + }; +}; + +&switch { + status = "okay"; + + switch_mac_mode = ; + + qcom,port_phyinfo { + // MAC0 -> GE Phy -> QCA8337 Phy4 + port@0 { + port_id = <1>; + mdiobus = <&mdio0>; + phy_address = <7>; + // status = "disabled"; + }; + + // MAC1 ---SGMII---> QCA8337 SerDes + port@1 { + port_id = <2>; + forced-speed = <1000>; + forced-duplex = <1>; + }; + }; +}; + +// MAC0 -> GE Phy +&dp1 { + /* + * =============================================================== + * _______________________ _______________________ + * | IPQ5018 | | QCA8337 | + * | +------+ +--------+ | | +--------+ +------+ | + * | | MAC0 |---| GE Phy |-+--UTP--+-| Phy4 |---| MAC5 | | + * | +------+ +--------+ | | +--------+ +------+ | + * | +------+ +--------+ | | +--------+ +------+ | + * | | MAC1 |---| Uniphy |-+-SGMII-+-| SerDes |---| MAC0 | | + * | +------+ +--------+ | | +--------+ +------+ | + * |_______________________| |_______________________| + * + * =============================================================== + * + * Current drivers don't support such topology. So dp1 and ge_phy + * are useless. But they can't be disabled dut to qca-ssdk use + * ge_phy to detect IPQ5018 dummy switch. + */ + status = "okay"; +}; + +// MAC1 ---SGMII---> QCA8337 SerDes +&dp2 { + status = "okay"; + phy-mode = "sgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&mdio0 { + status = "okay"; +}; + +// IPQ5018 GE Phy -> QCA8337 Phy1 +&ge_phy { + status = "okay"; +}; + +&mdio1 { + status = "okay"; + + pinctrl-0 = <&mdio1_pins>; + pinctrl-names = "default"; + reset-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>; + + // QCA8337 Phy0 -> IPQ5018 GE Phy + qca8337_0: ethernet-phy@0 { + reg = <0>; + }; + + // QCA8337 Phy1 -> WAN + qca8337_1: ethernet-phy@1 { + reg = <1>; + }; + + // QCA8337 Phy2 -> LAN1 + qca8337_2: ethernet-phy@2 { + reg = <2>; + }; + + // QCA8337 Phy3 -> LAN2 + qca8337_3: ethernet-phy@3 { + reg = <3>; + }; + + // QCA8337 Phy4 -> LAN3 + qca8337_4: ethernet-phy@4 { + reg = <4>; + }; + + // QCA8337 switch + switch1: ethernet-switch@17 { + compatible = "qca,qca8337"; + reg = <17>; + #address-cells = <1>; + #size-cells = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + label = "cpu1"; + phy-handle = <&qca8337_0>; + status = "disabled"; + }; + + port@2 { + reg = <2>; + label = "wan"; + phy-handle = <&qca8337_1>; + }; + + port@3 { + reg = <3>; + label = "lan1"; + phy-handle = <&qca8337_2>; + }; + + port@4 { + reg = <4>; + label = "lan2"; + phy-handle = <&qca8337_3>; + }; + + port@5 { + reg = <5>; + label = "lan3"; + phy-handle = <&qca8337_4>; + }; + + port@6 { + reg = <6>; + label = "cpu"; + phy-mode = "sgmii"; + ethernet = <&dp2>; + qca,sgmii-enable-pll; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; +}; + +&sleep_clk { + clock-frequency = <32000>; +}; + +&xo_board_clk { + clock-frequency = <24000000>; +}; + +&blsp1_uart1 { + status = "okay"; + + pinctrl-0 = <&serial_0_pins>; + pinctrl-names = "default"; +}; + +&crypto { + status = "okay"; +}; + +&cryptobam { + status = "okay"; +}; + +&prng { + status = "okay"; +}; + +&pwm { + status = "okay"; + + #pwm-cells = <2>; + pinctrl-0 = <&pwm_pins>; + pinctrl-names = "default"; +}; + +&qfprom { + status = "okay"; +}; + +&qpic_bam { + status = "okay"; +}; + +&qpic_nand { + pinctrl-0 = <&qpic_pins>; + pinctrl-names = "default"; + status = "okay"; + + partitions { + status = "disabled"; + }; + + nand@0 { + compatible = "spi-nand"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + + nand-ecc-engine = <&qpic_nand>; + + nand-ecc-strength = <8>; + nand-ecc-step-size = <512>; + nand-bus-width = <8>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "0:SBL1"; + reg = <0x00000000 0x80000>; + read-only; + }; + + partition@80000 { + label = "0:MIBIB"; + reg = <0x00080000 0x20000>; + read-only; + }; + + partition@100000 { + label = "0:QSEE"; + reg = <0x00100000 0x100000>; + read-only; + }; + + partition@200000 { + label = "0:DEVCFG"; + reg = <0x00200000 0x40000>; + read-only; + }; + + partition@240000 { + label = "0:CDT"; + reg = <0x00240000 0x40000>; + read-only; + }; + + partition@280000 { + label = "0:APPSBLENV"; + reg = <0x00280000 0x20000>; + }; + + partition@300000 { + label = "0:APPSBL"; + reg = <0x00300000 0x140000>; + read-only; + }; + + partition@440000 { + compatible = "nvmem-cells"; + label = "0:ART"; + reg = <0x00440000 0x100000>; + #address-cells = <1>; + #size-cells = <1>; + read-only; + }; + + partition@540000 { + label = "0:TRAINING"; + reg = <0x00540000 0x80000>; + read-only; + }; + + partition@5c0000 { + label = "u_env"; + reg = <0x005c0000 0x80000>; + }; + + partition@640000 { + label = "s_env"; + reg = <0x00640000 0x40000>; + }; + + partition@680000 { + label = "devinfo"; + reg = <0x00680000 0x40000>; + read-only; + }; + + partition@6c0000 { + label = "kernel"; + reg = <0x006c0000 0x5200000>; + }; + + partition@ec0000 { + label = "rootfs"; + reg = <0x0ec0000 0x4a00000>; + }; + + partition@58c0000 { + label = "alt_kernel"; + reg = <0x058c0000 0x5200000>; + }; + + partition@60c0000 { + label = "alt_rootfs"; + reg = <0x060c0000 0x4a00000>; + }; + + partition@aac0000 { + label = "sysdiag"; + reg = <0x0aac0000 0x200000>; + read-only; + }; + + partition@acc0000 { + label = "syscfg"; + reg = <0x0acc0000 0x4400000>; + read-only; + }; + }; + }; +}; + +&tlmm { + button_pins: button-state { + pins = "gpio27", "gpio28"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + }; + + mdio1_pins: mdio-state { + mdc-pins { + pins = "gpio36"; + function = "mdc"; + drive-strength = <8>; + bias-pull-up; + }; + + mdio-pins { + pins = "gpio37"; + function = "mdio"; + drive-strength = <8>; + bias-pull-up; + }; + }; + + pwm_pins: pwm-state { + mux_1 { + pins = "gpio1"; + function = "pwm1"; + drive-strength = <8>; + }; + + mux_2 { + pins = "gpio30"; + function = "pwm3"; + drive-strength = <8>; + }; + + mux_3 { + pins = "gpio46"; + function = "pwm0"; + drive-strength = <8>; + }; + }; + + qpic_pins: qpic-state { + clock-pins { + pins = "gpio9"; + function = "qspi_clk"; + drive-strength = <8>; + bias-disable; + }; + + cs-pins { + pins = "gpio8"; + function = "qspi_cs"; + drive-strength = <8>; + bias-disable; + }; + + data-pins { + pins = "gpio4", "gpio5", "gpio6", "gpio7"; + function = "qspi_data"; + drive-strength = <8>; + bias-disable; + }; + }; + + serial_0_pins: uart0-state { + pins = "gpio20", "gpio21"; + function = "blsp0_uart0"; + bias-disable; + }; +}; + +&tsens { + status = "okay"; +}; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx2000.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx2000.dts new file mode 100644 index 00000000000..44465ab885b --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx2000.dts @@ -0,0 +1,152 @@ +/dts-v1/; + +#include "ipq5018.dtsi" +#include "ipq5018-mx-atlas6.dtsi" + +#include +#include +#include + +/ { + model = "Linksys MX2000"; + compatible = "linksys,mx2000", "qcom,ipq5018"; +}; + +&q6v5_wcss { + status = "okay"; + + memory-region = <&q6_mem_regions>; + firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt", + "ath11k/IPQ5018/hw1.0/m3_fw.mdt", + "ath11k/qcn6122/hw1.0/m3_fw.mdt"; + + /*TODO: add support for v1 bootargs in mpd driver to control below settings*/ + /*qcom,bootargs_smem = <507>; hard-coded in mpd driver */ + /*boot-args = < */ + /* type: 0x1 PCIE0 */ + /* length: 4 */ + /* PD id: 3 */ + /* reset GPIO: 15 */ + /* reserved: 0 0>; */ + /* driver currently doesn't support passing bootargs */ + + // IPQ5018 + q6_wcss_pd1: pd-1 { + firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt"; + + resets = + <&gcc GCC_WCSSAON_RESET>, + <&gcc GCC_WCSS_BCR>, + <&gcc GCC_CE_BCR>; + reset-names = + "wcss_aon_reset", + "wcss_reset", + "ce_reset"; + + clocks = + <&gcc GCC_WCSS_AHB_S_CLK>, + <&gcc GCC_WCSS_ACMT_CLK>, + <&gcc GCC_WCSS_AXI_M_CLK>; + clock-names = + "gcc_wcss_ahb_s_clk", + "gcc_wcss_acmt_clk", + "gcc_wcss_axi_m_clk"; + + // qcom,halt-regs = <&tcsr_q6_block 0xa000 0xd000 0x0>; + interrupts-extended = + <&wcss_smp2p_in 8 0>, + <&wcss_smp2p_in 9 0>, + <&wcss_smp2p_in 12 0>, + <&wcss_smp2p_in 11 0>; + interrupt-names = + "fatal", + "ready", + "spawn-ack", + "stop-ack"; + + qcom,smem-states = + <&wcss_smp2p_out 8>, + <&wcss_smp2p_out 9>, + <&wcss_smp2p_out 10>; + qcom,smem-state-names = + "shutdown", + "stop", + "spawn"; + status = "okay"; + }; + + // QCN6102 6G + q6_wcss_pd2: pd-2 { + firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt"; + + interrupts-extended = + <&wcss_smp2p_in 16 0>, + <&wcss_smp2p_in 17 0>, + <&wcss_smp2p_in 20 0>, + <&wcss_smp2p_in 19 0>; + interrupt-names = + "fatal", + "ready", + "spawn-ack", + "stop-ack"; + + qcom,smem-states = + <&wcss_smp2p_out 16>, + <&wcss_smp2p_out 17>, + <&wcss_smp2p_out 18>; + qcom,smem-state-names = + "shutdown", + "stop", + "spawn"; + status = "disabled"; + }; + + // QCN6102 5G + q6_wcss_pd3: pd-3 { + firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt"; + + interrupts-extended = + <&wcss_smp2p_in 24 0>, + <&wcss_smp2p_in 25 0>, + <&wcss_smp2p_in 28 0>, + <&wcss_smp2p_in 27 0>; + interrupt-names = + "fatal", + "ready", + "spawn-ack", + "stop-ack"; + + qcom,smem-states = + <&wcss_smp2p_out 24>, + <&wcss_smp2p_out 25>, + <&wcss_smp2p_out 26>; + qcom,smem-state-names = + "shutdown", + "stop", + "spawn"; + status = "okay"; + }; +}; + +&wifi0 { + // IPQ5018 + qcom,rproc = <&q6_wcss_pd1>; + qcom,userpd-subsys-name = "q6v5_wcss_userpd1"; + qcom,ath11k-calibration-variant = "Linksys-MX2000"; + qcom,ath11k-fw-memory-mode = <2>; + qcom,bdf-addr = <0x4c400000>; + + status = "okay"; +}; + +&wifi1 { + // QCN6102 5G + qcom,rproc = <&q6_wcss_pd3>; + qcom,userpd-subsys-name = "q6v5_wcss_userpd3"; + qcom,ath11k-calibration-variant = "Linksys-MX2000"; + qcom,ath11k-fw-memory-mode = <2>; + qcom,bdf-addr = <0x4d100000>; + qcom,m3-dump-addr = <0x4df00000>; + + status = "okay"; +}; \ No newline at end of file diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx5500.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx5500.dts new file mode 100644 index 00000000000..146ccec51d3 --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx5500.dts @@ -0,0 +1,102 @@ +/dts-v1/; + +#include "ipq5018.dtsi" +#include "ipq5018-mx-atlas6.dtsi" + +#include +#include +#include + +/ { + model = "Linksys MX5500"; + compatible = "linksys,mx5500", "qcom,ipq5018"; +}; + +&pcie_x2phy { + status = "okay"; +}; + +&pcie_x2 { + status = "okay"; + + perst-gpios = <&tlmm 15 GPIO_ACTIVE_LOW>; + + bridge@0,0 { + reg = <0x00000000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + ranges; + + wifi@1,0 { + status = "okay"; + + /* QCN9074: ath11k lacks DT compatible for PCI cards */ + compatible = "pci17cb,1104"; + reg = <0x00010000 0 0 0 0>; + + qcom,ath11k-calibration-variant = "Linksys-MX5500"; + }; + }; +}; + +&q6v5_wcss { + status = "okay"; + + memory-region = <&q6_mem_regions>; + firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt", + "ath11k/IPQ5018/hw1.0/m3_fw.mdt"; + + // IPQ5018 + q6_wcss_pd1: pd-1 { + firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt"; + + resets = + <&gcc GCC_WCSSAON_RESET>, + <&gcc GCC_WCSS_BCR>, + <&gcc GCC_CE_BCR>; + reset-names = + "wcss_aon_reset", + "wcss_reset", + "ce_reset"; + + clocks = + <&gcc GCC_WCSS_AHB_S_CLK>, + <&gcc GCC_WCSS_ACMT_CLK>, + <&gcc GCC_WCSS_AXI_M_CLK>; + clock-names = + "gcc_wcss_ahb_s_clk", + "gcc_wcss_acmt_clk", + "gcc_wcss_axi_m_clk"; + + interrupts-extended = + <&wcss_smp2p_in 8 0>, + <&wcss_smp2p_in 9 0>, + <&wcss_smp2p_in 12 0>, + <&wcss_smp2p_in 11 0>; + interrupt-names = + "fatal", + "ready", + "spawn-ack", + "stop-ack"; + + qcom,smem-states = + <&wcss_smp2p_out 8>, + <&wcss_smp2p_out 9>, + <&wcss_smp2p_out 10>; + qcom,smem-state-names = + "shutdown", + "stop", + "spawn"; + status = "okay"; + }; +}; + +&wifi0 { + // IPQ5018 + qcom,rproc = <&q6_wcss_pd1>; + qcom,ath11k-calibration-variant = "Linksys-MX5500"; + qcom,ath11k-fw-memory-mode = <2>; + qcom,bdf-addr = <0x4c400000>; + + status = "okay"; +}; \ No newline at end of file diff --git a/target/linux/qualcommax/image/ipq50xx.mk b/target/linux/qualcommax/image/ipq50xx.mk index 8b137891791..1f3169161cc 100644 --- a/target/linux/qualcommax/image/ipq50xx.mk +++ b/target/linux/qualcommax/image/ipq50xx.mk @@ -1 +1,32 @@ +define Device/linksys_mx_atlas6 + $(call Device/FitImageLzma) + DEVICE_VENDOR := Linksys + BLOCKSIZE := 128k + PAGESIZE := 2048 + KERNEL_SIZE := 8192k + IMAGE_SIZE := 83968k + NAND_SIZE := 256m + SOC := ipq5018 + UBINIZE_OPTS := -E 5 # EOD marks to "hide" factory sig at EOF + IMAGES += factory.bin + IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi | linksys-image type=$$$$(DEVICE_MODEL) +endef +define Device/linksys_mx2000 + $(call Device/linksys_mx_atlas6) + DEVICE_MODEL := MX2000 + DEVICE_DTS_CONFIG := config@mp03.5-c1 + DEVICE_PACKAGES := ath11k-firmware-qcn6122 \ + ipq-wifi-linksys_mx2000 +endef +TARGET_DEVICES += linksys_mx2000 + +define Device/linksys_mx5500 + $(call Device/linksys_mx_atlas6) + DEVICE_MODEL := MX5500 + DEVICE_DTS_CONFIG := config@mp03.1 + DEVICE_PACKAGES := kmod-ath11k-pci \ + ath11k-firmware-qcn9074 \ + ipq-wifi-linksys_mx5500 +endef +TARGET_DEVICES += linksys_mx5500 \ No newline at end of file diff --git a/target/linux/qualcommax/ipq50xx/base-files/etc/board.d/02_network b/target/linux/qualcommax/ipq50xx/base-files/etc/board.d/02_network new file mode 100644 index 00000000000..bcf606c7568 --- /dev/null +++ b/target/linux/qualcommax/ipq50xx/base-files/etc/board.d/02_network @@ -0,0 +1,45 @@ +#!/bin/sh + +. /lib/functions/uci-defaults.sh +. /lib/functions/system.sh + +ipq50xx_setup_interfaces() +{ + local board="$1" + case $board in + linksys,mx2000|\ + linksys,mx5500) + ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" "wan" + ;; + esac +} + +ipq50xx_setup_macs() +{ + local board="$1" + local lan_mac="" + local wan_mac="" + local label_mac="" + + case "$board" in + linksys,mx2000|\ + linksys,mx5500) + label_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr) + lan_mac=$label_mac + wan_mac=$label_mac + ucidef_set_network_device_mac eth1 $label_mac + ;; + esac + + [ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac + [ -n "$wan_mac" ] && ucidef_set_interface_macaddr "wan" $wan_mac + [ -n "$label_mac" ] && ucidef_set_label_macaddr $label_mac +} + +board_config_update +board=$(board_name) +ipq50xx_setup_interfaces $board +ipq50xx_setup_macs $board +board_config_flush + +exit 0 diff --git a/target/linux/qualcommax/ipq50xx/base-files/etc/hotplug.d/firmware/11-ath11k-caldata b/target/linux/qualcommax/ipq50xx/base-files/etc/hotplug.d/firmware/11-ath11k-caldata new file mode 100644 index 00000000000..ad1e0f15352 --- /dev/null +++ b/target/linux/qualcommax/ipq50xx/base-files/etc/hotplug.d/firmware/11-ath11k-caldata @@ -0,0 +1,47 @@ +#!/bin/sh + +[ -e /lib/firmware/$FIRMWARE ] && exit 0 + +. /lib/functions/caldata.sh + +board=$(board_name) + +case "$FIRMWARE" in +"ath11k/IPQ5018/hw1.0/cal-ahb-c000000.wifi.bin") + case "$board" in + linksys,mx2000|\ + linksys,mx5500) + caldata_extract "0:ART" 0x1000 0x20000 + label_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr) + ath11k_patch_mac $(macaddr_add $label_mac 1) 0 + ath11k_remove_regdomain + ath11k_set_macflag + ;; + esac + ;; +"ath11k/qcn6122/hw1.0/cal-ahb-soc@0:wifi1@c000000.bin") + case "$board" in + linksys,mx2000) + caldata_extract "0:ART" 0x26800 0x20000 + label_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr) + ath11k_patch_mac $(macaddr_add $label_mac 2) 0 + ath11k_remove_regdomain + ath11k_set_macflag + ;; + esac + ;; +"ath11k/QCN9074/hw1.0/cal-pci-0001:01:00.0.bin") + case "$board" in + linksys,mx5500) + caldata_extract "0:ART" 0x26800 0x20000 + label_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr) + ath11k_patch_mac $(macaddr_add $label_mac 2) 0 + ath11k_remove_regdomain + ath11k_set_macflag + ;; + esac + ;; +*) + exit 1 + ;; +esac diff --git a/target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount b/target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount new file mode 100755 index 00000000000..b570428aef0 --- /dev/null +++ b/target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount @@ -0,0 +1,12 @@ +#!/bin/sh /etc/rc.common + +START=99 + +boot() { + case $(board_name) in + linksys,mx2000|\ + linksys,mx5500) + mtd resetbc s_env || true + ;; + esac +} diff --git a/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/linksys.sh b/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/linksys.sh new file mode 100644 index 00000000000..18366fc622a --- /dev/null +++ b/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/linksys.sh @@ -0,0 +1,125 @@ +linksys_get_target_firmware() { + local cur_boot_part mtd_ubi0 + + cur_boot_part="$(/usr/sbin/fw_printenv -n boot_part)" + if [ -z "${cur_boot_part}" ]; then + mtd_ubi0=$(cat /sys/class/ubi/ubi0/mtd_num) + case "$(grep -E "^mtd${mtd_ubi0}:" /proc/mtd | cut -d '"' -f 2)" in + kernel|rootfs) + cur_boot_part=1 + ;; + alt_kernel|alt_rootfs) + cur_boot_part=2 + ;; + esac + >&2 printf "Current boot_part='%s' selected from ubi0/mtd_num='%s'" \ + "${cur_boot_part}" "${mtd_ubi0}" + fi + + # OEM U-Boot for EA6350v3, EA8300 and MR8300; bootcmd= + # if test $auto_recovery = no; + # then bootipq; + # elif test $boot_part = 1; + # then run bootpart1; + # else run bootpart2; + # fi + + case "$cur_boot_part" in + 1) + fw_setenv -s - <<-EOF + boot_part 2 + auto_recovery yes + EOF + printf "alt_kernel" + return + ;; + 2) + fw_setenv -s - <<-EOF + boot_part 1 + auto_recovery yes + EOF + printf "kernel" + return + ;; + *) + return + ;; + esac +} + +linksys_is_factory_image() { + local board=$(board_name) + board=${board##*,} + + # check matching footer signature + tail -c 256 $1 | grep -q -i "\.LINKSYS\.........${board}" +} + +platform_do_upgrade_linksys() { + local magic_long="$(get_magic_long "$1")" + + local rm_oem_fw_vols="squashfs ubifs" # from OEM [alt_]rootfs UBI + local vol + + mkdir -p /var/lock + local part_label="$(linksys_get_target_firmware)" + touch /var/lock/fw_printenv.lock + + if [ -z "$part_label" ]; then + echo "cannot find target partition" + exit 1 + fi + + local target_mtd=$(find_mtd_part "$part_label") + + [ "$magic_long" = "73797375" ] && { + CI_KERNPART="$part_label" + if [ "$part_label" = "kernel" ]; then + CI_UBIPART="rootfs" + else + CI_UBIPART="alt_rootfs" + fi + + local mtdnum="$(find_mtd_index "$CI_UBIPART")" + if [ ! "$mtdnum" ]; then + echo "cannot find ubi mtd partition $CI_UBIPART" + return 1 + fi + + local ubidev="$(nand_find_ubi "$CI_UBIPART")" + if [ ! "$ubidev" ]; then + ubiattach -m "$mtdnum" + sync + ubidev="$(nand_find_ubi "$CI_UBIPART")" + fi + + if [ "$ubidev" ]; then + for vol in $rm_oem_fw_vols; do + ubirmvol "/dev/$ubidev" -N "$vol" 2>/dev/null + done + fi + + # complete std upgrade + if nand_upgrade_tar "$1" ; then + nand_do_upgrade_success + else + nand_do_upgrade_failed + fi + + } + + [ "$magic_long" = "27051956" ] && { + echo "writing \"$1\" image to \"$part_label\"" + get_image "$1" | mtd write - "$part_label" + } + + [ "$magic_long" = "d00dfeed" ] && { + if ! linksys_is_factory_image "$1"; then + echo "factory image doesn't match device" + return 1 + fi + + echo "writing \"$1\" factory image to \"$part_label\"" + get_image "$1" | mtd -e "$part_label" write - "$part_label" + } +} diff --git a/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh b/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh new file mode 100644 index 00000000000..5be51c77fd6 --- /dev/null +++ b/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh @@ -0,0 +1,32 @@ +PART_NAME=firmware +REQUIRE_IMAGE_METADATA=1 + +RAMFS_COPY_BIN='fw_printenv fw_setenv head' +RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock' + +platform_check_image() { + return 0; +} + +platform_do_upgrade() { + case "$(board_name)" in + linksys,mx2000|\ + linksys,mx5500) + boot_part="$(fw_printenv -n boot_part)" + if [ "$boot_part" -eq "1" ]; then + fw_setenv boot_part 2 + CI_KERNPART="alt_kernel" + CI_UBIPART="alt_rootfs" + else + fw_setenv boot_part 1 + CI_UBIPART="rootfs" + fi + fw_setenv boot_part_ready 3 + fw_setenv auto_recovery yes + nand_do_upgrade "$1" + ;; + *) + default_do_upgrade "$1" + ;; + esac +}