[openwrt/openwrt] qualcommax: ipq50xx: add support for Linksys MX6200

LEDE Commits lede-commits at lists.infradead.org
Sun Jan 4 10:07:47 PST 2026


robimarko pushed a commit to openwrt/openwrt.git, branch openwrt-25.12:
https://git.openwrt.org/8f0d7ae61b609fa657fae1168ff5ffabc7432535

commit 8f0d7ae61b609fa657fae1168ff5ffabc7432535
Author: George Moussalem <george.moussalem at outlook.com>
AuthorDate: Mon Jun 2 15:21:36 2025 +0400

    qualcommax: ipq50xx: add support for Linksys MX6200
    
    Linksys MX6200 is a triband Wi-Fi 6E wireless router.
    
    Speficiations:
    * SoC: Qualcomm IPQ5018 (64-bit dual-core ARM Cortex-A53 @ 1.0Ghz)
    * Memory: Nanya NT5CC256M16ER-EK (512 MiB DDR3-933)
    * Serial Port: 3v3 TTL 115200n8
    * Wi-Fi: IPQ5018 (2x2 2.4 Ghz 802.11b/g/n/ax)
             QCN6102 (2x2:2 5 Ghz 802.11an/ac/ax)
             QCN6122 (2x2:2 6 Ghz 802.11an/ac/ax)
    * Ethernet: IPQ5018 integrated virtual switch connected to:
                - LAN Port: Internal IPQ5018 GE PHY
                - WAN Port: Maxlinear Ethernet GPY115C PHY
    * Flash: Macronix MX35UF2GE4AD (256 MiB)
    * LEDs: 1x multi-color PWM LED
    * Buttons: 1x WPS (GPIO 27 Active Low)
               1x Reset (GPIO 28 Acive Low)
    * FCC ID: 2AYRA-08436
    
    Flash instructions:
    ************************************************************************
    NOTE: serial access is required! Although the web UI allows you to
    install the Openwrt image, secure boot is enabled which will prevent
    booting an unsigned image. The boot sequence must be adjusted in U-boot
    to allow booting unsigned images.
    ************************************************************************
    
    1. On OEM firmware, login to the web UI (typically @ http://192.168.1.1)
    and click 'CA' in the bottom right corner.
    Then click -> Connectivity -> Manual Upgrade.
    Alternatively, browse to
    http://<router IP>/fwupdate.html.
    Upload openwrt-qualcommax-ipq50xx-linksys_mx6200-squashfs-factory.ubi.
    Continue with step 5.
    2. Installation on alternate partition using serial connection from OEM
    firmware (default login: root, password: admin):
    flash_erase /dev/mtd19 0 0
    nandwrite -p /dev/mtd19 openwrt-qualcommax-ipq50xx-linksys_mx6200-squashfs-factory.ubi
    reboot
    Continue with step 5.
    3. Installation using serial connection from initramfs
    setup tftp server listening on IP in 192.168.1.0/24 (other than the
    router IP 192.168.1.1). In U-boot, load the initramfs image to memory:
    tftp $loadaddr <your IP>:openwrt-qualcommax-ipq50xx-linksys_mx6200-initramfs-uImage.itb
    boot the image using command:
    bootm $loadaddr
    when fully booted, scp the sysupgrade image to your router IP (default:
    192.168.1.1):
    scp -O <path>/openwrt-qualcommax-ipq50xx-linksys_mx6200-squashfs-sysypgrade.bin root at 192.168.1.1:/tmp/
    use sysupgrade to flash the image to nand:
    sysupgrade -n -v /tmp/openwrt-qualcommax-ipq50xx-linksys_mx6200-squashfs-sysupgrade.bin
    Continue with step 5.
    4. Optionally install on alternate partition. From Openwrt:
    mtd -r -e rootfs_1 -n write openwrt-qualcommax-ipq50xx-linksys_mx6200-squashfs-factory.ubi rootfs_1
    Continue with step 5.
    5. Setup U-boot for ability to dual boot signed (stock) and non-signed
    (Openwrt) images with auto-detection.
    From U-boot, run (be aware: copy line by line):
    setenv setnandbootargs 'setenv bootargs init=/sbin/init ubi.mtd=rootfs rootfstype=squashfs rootwait'
    setenv nandinitcmd 'setenv mtdids nand0=nand0; run setrootfscmd; ubi part rootfs 2048'
    setenv setrootfscmd 'if test $boot_part = 1; then setenv mtdparts mtdparts=nand0:0x${imgsize}@0x${prikern}(rootfs); else setenv mtdparts mtdparts=nand0:0x${imgsize}@0x${altkern}(rootfs); fi'
    setenv readhdr1cmd 'ubi read $loadaddr kernel 0x40; setexpr IMGOFF $loadaddr + 0x10; setexpr CODEOFF $loadaddr + 0x14; setexpr SIGOFF $loadaddr + 0x1c; setexpr CERTOFF $loadaddr + 0x24'
    setenv readhdr2cmd 'setexpr.l HDR *$loadaddr; setexpr.l IMGSZ *$IMGOFF; setexpr.l CODESZ *$CODEOFF; setexpr.l SIGSZ *$SIGOFF; setexpr.l CERTSZ *$CERTOFF; setexpr TSIZE $CODESZ + $SIGSZ; setexpr TSIZE $TSIZE + $CERTSZ'
    setenv testmbncmd 'if test $HDR -ne edfe0dd0 -a $IMGSZ -eq $TSIZE; then bootipq; else ubi read $loadaddr kernel $kernsize; run setnandbootargs; bootm $loadaddr; fi'
    setenv bootcmd2 'if test $auto_recovery = no; then bootipq; else run nandinitcmd; run readhdr1cmd; run readhdr2cmd; run testmbncmd; fi'
    setenv bootcmd 'run bootcmd2'
    saveenv
    6. Back to the OEM firmware.
    Download firmware from OEM website:
    MX6200: https://support.linksys.com/kb/article/408-en/
    From serial/SSH, in Openwrt, flash OEM firmware to alternate partition:
    mtd -r -e rootfs_1 -n write FW_MX6200_1.0.11.216041_prod.signed.img rootfs_1
    
    Switching active partition:
    1. From U-boot, executive the following to switch to partition 1:
    setenv boot_part 1
    for partition 2:
    setenv boot_part 2
    2. From Openwrt:
    fw_printenv boot_part
    In case it's 1:
    fw_setenv boot_part 2
    . /lib/upgrade/platform.sh
    linksys_bootconfig_set_primaryboot "0:bootconfig" 1
    linksys_bootconfig_set_primaryboot "0:bootconfig1" 1
    In case it's 2:
    fw_setenv boot_part 1
    . /lib/upgrade/platform.sh
    linksys_bootconfig_set_primaryboot "0:bootconfig" 0
    linksys_bootconfig_set_primaryboot "0:bootconfig1" 0
    and
    reboot
    
    Signed-off-by: George Moussalem <george.moussalem at outlook.com>
    Link: https://github.com/openwrt/openwrt/pull/21038
    Link: https://github.com/openwrt/openwrt/pull/21273
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 .../uboot-envtools/files/qualcommax_ipq50xx        |   1 +
 package/firmware/ipq-wifi/Makefile                 |   2 +
 .../arch/arm64/boot/dts/qcom/ipq5018-mx6200.dts    | 128 +++++++++++++++++++++
 target/linux/qualcommax/image/ipq50xx.mk           |  18 +++
 .../ipq50xx/base-files/etc/board.d/02_network      |   1 +
 .../etc/hotplug.d/firmware/11-ath11k-caldata       |  25 ++++
 .../ipq50xx/base-files/etc/init.d/bootcount        |   1 +
 .../ipq50xx/base-files/lib/upgrade/platform.sh     |   5 +
 target/linux/qualcommax/ipq50xx/config-default     |   1 +
 9 files changed, 182 insertions(+)

diff --git a/package/boot/uboot-tools/uboot-envtools/files/qualcommax_ipq50xx b/package/boot/uboot-tools/uboot-envtools/files/qualcommax_ipq50xx
index d4169fa663..d8542a9aac 100644
--- a/package/boot/uboot-tools/uboot-envtools/files/qualcommax_ipq50xx
+++ b/package/boot/uboot-tools/uboot-envtools/files/qualcommax_ipq50xx
@@ -19,6 +19,7 @@ glinet,gl-b3000)
 linksys,mr5500|\
 linksys,mx2000|\
 linksys,mx5500|\
+linksys,mx6200|\
 linksys,spnmx56)
 	ubootenv_add_mtd "u_env" "0x0" "0x40000" "0x20000"
 	;;
diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile
index 1106de7fc4..a1a3e6a798 100644
--- a/package/firmware/ipq-wifi/Makefile
+++ b/package/firmware/ipq-wifi/Makefile
@@ -55,6 +55,7 @@ ALLWIFIBOARDS:= \
 	linksys_mx4200 \
 	linksys_mx5300 \
 	linksys_mx5500 \
+	linksys_mx6200 \
 	linksys_mx8500 \
 	linksys_spnmx56 \
 	linksys_whw03 \
@@ -235,6 +236,7 @@ $(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_mx6200,Linksys MX6200))
 $(eval $(call generate-ipq-wifi-package,linksys_mx8500,Linksys MX8500))
 $(eval $(call generate-ipq-wifi-package,linksys_spnmx56,Linksys SPNMX56))
 $(eval $(call generate-ipq-wifi-package,linksys_whw03,Linksys WHW03))
diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx6200.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx6200.dts
new file mode 100644
index 0000000000..250fe39075
--- /dev/null
+++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx6200.dts
@@ -0,0 +1,128 @@
+/dts-v1/;
+
+#include "ipq5018.dtsi"
+#include "ipq5018-mx-base.dtsi"
+#include "ipq5018-qcn6122.dtsi"
+
+/ {
+	model = "Linksys MX6200";
+	compatible = "linksys,mx6200", "qcom,ipq5018";
+
+	chosen {
+		bootargs-append = " root=/dev/ubiblock0_1 coherent_pool=2M";
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+/*
+* =================================================================
+*     _______________________             ____________
+*    |        IPQ5018        |           |            |
+*    | +------+   +--------+ |           | +--------+ |
+*    | | MAC0 |---| GE Phy |-+--- MDI ---+ | RJ45   | +
+*    | +------+   +--------+ |           | +--------+ |
+*    |                       |           |____________|
+*    |                       |            _______________________
+*    |                       |           |    MXL GPY115C Phy    |
+*    | +------+   +--------+ |           | +--------+   +------+ |
+*    | | MAC1 |---| Uniphy |-+-- SGMII---+ | Phy    |---| RJ45 | |
+*    | +------+   +--------+ |           | +--------+   +------+ |
+*    |_______________________|           |_______________________|
+*
+* =================================================================
+ */
+
+&switch {
+	status = "okay";
+
+	switch_mac_mode = <MAC_MODE_SGMII_CHANNEL0>;
+
+	qcom,port_phyinfo {
+		// MAC0 -> GE Phy -> MDI --> RJ45
+		port at 0 {
+			port_id = <1>;
+			mdiobus = <&mdio0>;
+			phy_address = <7>;
+		};
+
+		// MAC1 ---SGMII---> MaxLinear PHY -> RJ45
+		port at 1 {
+			port_id = <2>;
+			mdiobus = <&mdio1>;
+			phy_address = <15>;
+			port_mac_sel = "QGMAC_PORT";
+		};
+	};
+};
+
+// MAC0 ---MDI---> IPQ5018 GE PHY
+&dp1 {
+	status = "okay";
+
+	label = "lan";
+	phy-handle = <&ge_phy>;
+	nvmem-cells = <&hw_mac_addr 1>;
+	nvmem-cell-names = "mac-address";
+};
+
+// MAC1 ---SGMII---> MXL Phy
+&dp2 {
+	status = "okay";
+
+	label = "wan";
+	phy-handle = <&gpy115c>;
+	nvmem-cells = <&hw_mac_addr 0>;
+	nvmem-cell-names = "mac-address";
+};
+
+&mdio0 {
+	status = "okay";
+};
+
+&mdio1 {
+	status = "okay";
+
+	pinctrl-0 = <&mdio1_pins>;
+	pinctrl-names = "default";
+	reset-gpios = <&tlmm 24 GPIO_ACTIVE_LOW>;
+
+	// Maxlinear Ethernet GPY115C
+	gpy115c: ethernet-phy at f {
+		compatible = "ethernet-phy-id67c9.df10";
+		reg = <15>;
+	};
+};
+
+&q6_region {
+	reg = <0x0 0x4b000000 0x0 0x4d00000>;
+};
+
+&wifi {
+	status = "okay";
+
+	qcom,rproc = <&q6_wcss_pd1>;
+	qcom,ath11k-calibration-variant = "Linksys-MX6200";
+	qcom,ath11k-fw-memory-mode = <1>;
+	qcom,bdf-addr = <0x4c400000>;
+};
+
+&wifi1 {
+	status = "okay";
+
+	qcom,rproc = <&q6_wcss_pd2>;
+	qcom,userpd-subsys-name = "q6v5_wcss_userpd2";
+	qcom,ath11k-calibration-variant = "Linksys-MX6200-5G";
+	qcom,ath11k-fw-memory-mode = <1>;
+	qcom,m3-dump-addr = <0x4df00000>;
+};
+
+&wifi2 {
+	status = "okay";
+
+	qcom,rproc = <&q6_wcss_pd3>;
+	qcom,userpd-subsys-name = "q6v5_wcss_userpd3";
+	qcom,ath11k-calibration-variant = "Linksys-MX6200-6G";
+	qcom,ath11k-fw-memory-mode = <1>;
+	qcom,bdf-addr = <0x4e500000>;
+	qcom,m3-dump-addr = <0x4f200000>;
+};
diff --git a/target/linux/qualcommax/image/ipq50xx.mk b/target/linux/qualcommax/image/ipq50xx.mk
index 6a6a50d6f7..be247c7df9 100644
--- a/target/linux/qualcommax/image/ipq50xx.mk
+++ b/target/linux/qualcommax/image/ipq50xx.mk
@@ -136,6 +136,24 @@ define Device/linksys_mx5500
 endef
 TARGET_DEVICES += linksys_mx5500
 
+define Device/linksys_mx6200
+	$(call Device/FitImage)
+	$(call Device/UbiFit)
+	DEVICE_VENDOR := Linksys
+	DEVICE_MODEL := MX6200
+	BLOCKSIZE := 128k
+	PAGESIZE := 2048
+	DEVICE_DTS_CONFIG := config at mp03.5-c1
+	KERNEL_SIZE := 8192k
+	IMAGE_SIZE := 51200k
+	NAND_SIZE := 256m
+	SOC := ipq5018
+	IMAGE/factory.ubi := append-ubi | linksys-image type=$$$$(DEVICE_MODEL)
+	DEVICE_PACKAGES := ath11k-firmware-ipq5018-qcn6122 \
+		ipq-wifi-linksys_mx6200
+endef
+TARGET_DEVICES += linksys_mx6200
+
 define Device/linksys_spnmx56
 	$(call Device/linksys_ipq50xx_mx_base)
 	DEVICE_MODEL := SPNMX56
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
index 05bed90e27..4bcd7dd5df 100644
--- a/target/linux/qualcommax/ipq50xx/base-files/etc/board.d/02_network
+++ b/target/linux/qualcommax/ipq50xx/base-files/etc/board.d/02_network
@@ -22,6 +22,7 @@ ipq50xx_setup_interfaces()
 	xiaomi,ax6000)
 		ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" "wan"
 		;;
+	linksys,mx6200|\
 	yuncore,ax830|\
 	yuncore,ax850)
 		ucidef_set_interfaces_lan_wan "lan" "wan"
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
index 6cd00bf53c..cf48022aea 100644
--- 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
@@ -31,6 +31,13 @@ case "$FIRMWARE" in
 		ath11k_remove_regdomain
 		ath11k_set_macflag
 		;;
+	linksys,mx6200)
+		caldata_extract "0:art" 0x1000 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
+		;;
 	xiaomi,ax6000)
 		caldata_extract "0:art" 0x1000 0x20000
 		;;
@@ -65,6 +72,13 @@ case "$FIRMWARE" in
 		ath11k_remove_regdomain
 		ath11k_set_macflag
 		;;
+	linksys,mx6200)
+		caldata_extract "0:art" 0x26800 0x20000
+		label_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr)
+		ath11k_patch_mac $(macaddr_add $label_mac 3) 0
+		ath11k_remove_regdomain
+		ath11k_set_macflag
+		;;
 	yuncore,ax830)
 		caldata_extract "0:ART" 0x4c000 0x20000
 		label_mac=$(mtd_get_mac_binary 0:ART 0)
@@ -74,6 +88,17 @@ case "$FIRMWARE" in
 		;;
 	esac
 	;;
+"ath11k/QCN6122/hw1.0/cal-ahb-b00b040.wifi.bin")
+	case "$board" in
+	linksys,mx6200)
+		caldata_extract "0:art" 0x4c000 0x20000
+		label_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr)
+		ath11k_patch_mac $(macaddr_add $label_mac 4) 0
+		ath11k_remove_regdomain
+		ath11k_set_macflag
+		;;
+	esac
+	;;
 "ath11k/QCN9074/hw1.0/cal-pci-0000:01:00.0.bin")
 	case "$board" in
 	linksys,mr5500|\
diff --git a/target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount b/target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount
index 0e573a1407..efde13d43a 100755
--- a/target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount
+++ b/target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount
@@ -7,6 +7,7 @@ boot() {
 	linksys,mr5500|\
 	linksys,mx2000|\
 	linksys,mx5500|\
+	linksys,mx6200|\
 	linksys,spnmx56)
 		mtd resetbc s_env || true
 	;;
diff --git a/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh b/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh
index bbc6d8eb7f..24bacdb6b8 100644
--- a/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh
+++ b/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh
@@ -206,6 +206,11 @@ platform_do_upgrade() {
 		remove_oem_ubi_volume squashfs
 		nand_do_upgrade "$1"
 		;;
+	linksys,mx6200)
+		linksys_bootconfig_pre_upgrade "$1"
+		remove_oem_ubi_volume ubi_rootfs
+		nand_do_upgrade "$1"
+		;;
 	xiaomi,ax6000)
 		# Make sure that UART is enabled
 		fw_setenv boot_wait on
diff --git a/target/linux/qualcommax/ipq50xx/config-default b/target/linux/qualcommax/ipq50xx/config-default
index 97a342776a..33e5611af4 100644
--- a/target/linux/qualcommax/ipq50xx/config-default
+++ b/target/linux/qualcommax/ipq50xx/config-default
@@ -4,6 +4,7 @@ CONFIG_GRO_CELLS=y
 CONFIG_IPQ_CMN_PLL=y
 CONFIG_IPQ_GCC_5018=y
 CONFIG_LEDS_PWM=y
+CONFIG_MAXLINEAR_GPHY=y
 CONFIG_MTD_SPI_NAND=y
 CONFIG_NET_DEVLINK=y
 CONFIG_NET_DSA=y




More information about the lede-commits mailing list