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

LEDE Commits lede-commits at lists.infradead.org
Tue Feb 18 00:37:30 PST 2025


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/fe379eb1c1b004f7eef12981f761f6fc1369d7aa

commit fe379eb1c1b004f7eef12981f761f6fc1369d7aa
Author: George Moussalem <george.moussalem at outlook.com>
AuthorDate: Wed Jan 8 10:21:30 2025 +0400

    qualcommax: ipq50xx: add support for Linksys SPNMX56
    
    The SPNMX56 is an ISP-branded and distributed device similar to the MX5500
    with the same Wifi chips (IPQ5018 for 2.4G and QCN9074 for 5G) but has an
    additional QCA8081 PHY providing a 2.5gbps ethernet WAN port.
    
    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)
             QCN9024 (4x4:4 5 Ghz 802.11an/ac/ax)
    * Ethernet: IPQ5018 integrated virtual switch connected to an external
                QCA8337 switch (3 Ports 10/100/1000 GBASE-T) and a
                QCA8081 phy (up to 2.5 Gbps)
    * Flash: Gigadevice GD5F2GM7RExxG (256 MiB)
    * LEDs: 1x multi-color PWM LED
    * Buttons: 1x WPS (GPIO 27 Active Low)
               1x Reset (GPIO 28 Acive Low)
    
    Flash instructions:
    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://<router IP>/fwupdate.html
    Upload openwrt-qualcommax-ipq50xx-linksys_spnmx56-squashfs-factory.bin
    Optionally flash 2nd 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_spnmx56-squashfs-factory.bin kernel
    and in case of 1:
    mtd -r -e alt_kernel -n write openwrt-qualcommax-ipq50xx-linksys_spnmx56-squashfs-factory.bin alt_kernel
    2. Installation using serial connection from OEM firmware
    hit Enter once booted and enter credentials (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_spnmx56-squashfs-factory.bin
    or in case of 1:
    flash_erase /dev/mtd14 0 0
    nandwrite -p /dev/mtd14 openwrt-qualcommax-ipq50xx-linksys_spnmx56-squashfs-factory.bin
    After first boot install firmware on second partition:
    mtd -r -e kernel -n write openwrt-qualcommax-ipq50xx-linksys_spnmx56-squashfs-factory.bin kernel
    or:
    mtd -r -e alt_kernel -n write openwrt-qualcommax-ipq50xx-linksys_spnmx56-squashfs-factory.bin alt_kernel
    3. Back to the OEM firmware.
    Download firmware from OEM website:
    Firmware for this device cannot be searched for on the Linksys website.
    Instead, we'd have to use serial to intercept the URL of the firmware
    while it's trying to update. Firmware is ISP specific:
    Toob (UK): http://download.linksys.com/updates/20241125t080737/FW_MX56TB_1.0.1.216218_prod.img
    
    The intention is to collect URLs for different ISPs on a wiki page.
    
    From serial or SSH:
    fw_printenv boot_part
    in case of 1:
    mtd -r -e alt_kernel -n write FW_MX56TB_1.0.1.216218_prod.img alt_kernel
    else in case of 2:
    mtd -r -e kernel -n write FW_MX56TB_1.0.1.216218_prod.img kernel
    
    Signed-off-by: George Moussalem <george.moussalem at outlook.com>
    Link: https://github.com/openwrt/openwrt/pull/17968
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 .../boot/uboot-envtools/files/qualcommax_ipq50xx   |   3 +-
 package/firmware/ipq-wifi/Makefile                 |   2 +
 .../arch/arm64/boot/dts/qcom/ipq5018-spnmx56.dts   | 240 +++++++++++++++++++++
 target/linux/qualcommax/image/ipq50xx.mk           |  10 +
 .../ipq50xx/base-files/etc/board.d/02_network      |   6 +-
 .../etc/hotplug.d/firmware/11-ath11k-caldata       |   6 +-
 .../ipq50xx/base-files/etc/init.d/bootcount        |   3 +-
 .../ipq50xx/base-files/lib/upgrade/platform.sh     |   3 +-
 8 files changed, 266 insertions(+), 7 deletions(-)

diff --git a/package/boot/uboot-envtools/files/qualcommax_ipq50xx b/package/boot/uboot-envtools/files/qualcommax_ipq50xx
index 0e78bb8060..b63451d627 100644
--- a/package/boot/uboot-envtools/files/qualcommax_ipq50xx
+++ b/package/boot/uboot-envtools/files/qualcommax_ipq50xx
@@ -9,7 +9,8 @@ board=$(board_name)
 
 case "$board" in
 linksys,mx2000|\
-linksys,mx5500)
+linksys,mx5500|\
+linksys,spnmx56)
 	idx="$(find_mtd_index u_env)"
 	[ -n "$idx" ] && \
 		ubootenv_add_uci_config "/dev/mtd$idx" "0x0" "0x40000" "0x20000"
diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile
index f784d9a2e4..deeda4955e 100644
--- a/package/firmware/ipq-wifi/Makefile
+++ b/package/firmware/ipq-wifi/Makefile
@@ -45,6 +45,7 @@ ALLWIFIBOARDS:= \
 	linksys_mx5300 \
 	linksys_mx5500 \
 	linksys_mx8500 \
+	linksys_spnmx56 \
 	linksys_whw03 \
 	netgear_lbr20 \
 	netgear_rax120v2 \
@@ -184,6 +185,7 @@ $(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_spnmx56,Linksys SPNMX56))
 $(eval $(call generate-ipq-wifi-package,linksys_whw03,Linksys WHW03))
 $(eval $(call generate-ipq-wifi-package,netgear_lbr20,Netgear LBR20))
 $(eval $(call generate-ipq-wifi-package,netgear_rax120v2,Netgear RAX120v2))
diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-spnmx56.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-spnmx56.dts
new file mode 100644
index 0000000000..75b9444514
--- /dev/null
+++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-spnmx56.dts
@@ -0,0 +1,240 @@
+/dts-v1/;
+
+#include "ipq5018.dtsi"
+#include "ipq5018-mx-base.dtsi"
+
+/ {
+	model = "Linksys SPNMX56";
+	compatible = "linksys,spnmx56", "qcom,ipq5018";
+};
+
+/*
+* =================================================================
+*     _______________________             _______________________
+*    |        IPQ5018        |           |        QCA8337        |
+*    | +------+   +--------+ |           | +--------+   +------+ |
+*    | | MAC0 |---| GE Phy |-+--- MDI ---+ | Phy4   |---| MAC5 | |
+*    | +------+   +--------+ |           | +--------+   +------+ |
+*    |                       |           |_______________________|
+*    |                       |            _______________________
+*    |                       |           |        QCA8081        |
+*    | +------+   +--------+ |           | +--------+   +------+ |
+*    | | MAC1 |---| Uniphy |-+-- SGMII+--+ | Phy    |---| MAC  | |
+*    | +------+   +--------+ |           | +--------+   +------+ |
+*    |_______________________|           |_______________________|
+*
+* =================================================================
+*/
+
+&switch {
+	status = "okay";
+
+	switch_mac_mode = <MAC_MODE_SGMII_CHANNEL0>;
+
+	qcom,port_phyinfo {
+		// MAC0 -> GE Phy --- MDI --- QCA8337 Switch
+		port at 0 {
+			port_id = <1>;
+			mdiobus = <&mdio0>;
+			phy_address = <7>;
+			phy_dac = <0x10 0x10>;
+		};
+
+		// MAC1 -> Uniphy --- SGMII --- QCA8081
+		port at 1 {
+			port_id = <2>;
+			mdiobus = <&mdio1>;
+			phy_address = <28>;
+			port_mac_sel = "QGMAC_PORT";
+		};
+	};
+};
+
+// MAC0 -> GE Phy
+&dp1 {
+	status = "okay";
+};
+
+// MAC1 ---SGMII---> QCA8081
+&dp2 {
+	status = "okay";
+
+	label = "wan";
+	phy-handle = <&qca8081>;
+};
+
+&mdio0 {
+	status = "okay";
+};
+
+// IPQ5018 GE Phy -> QCA8337 PHY4
+&ge_phy {
+	qcom,dac = <0x10 0x10>;
+};
+
+&mdio1 {
+	status = "okay";
+
+	pinctrl-0 = <&mdio1_pins>;
+	pinctrl-names = "default";
+	reset-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>;
+
+	// Not connected
+	qca8337_0: ethernet-phy at 0 {
+		reg = <0>;
+	};
+
+	// QCA8337 Phy1 -> LAN1
+	qca8337_1: ethernet-phy at 1 {
+		reg = <1>;
+	};
+
+	// QCA8337 Phy2 -> LAN2
+	qca8337_2: ethernet-phy at 2 {
+		reg = <2>;
+	};
+
+	// QCA8337 Phy3 -> LAN3
+	qca8337_3: ethernet-phy at 3 {
+		reg = <3>;
+	};
+
+	// QCA8337 Phy4 -> MDI -> IPQ5018 GE PHY
+	qca8337_4: ethernet-phy at 4 {
+		reg = <4>;
+	};
+
+	// QCA8081 Phy -> WAN
+	qca8081: ethernet-phy at 28 {
+		compatible = "ethernet-phy-id004d.d101";
+		reg = <28>;
+		reset-deassert-us = <10000>;
+		reset-gpios = <&tlmm 24 GPIO_ACTIVE_LOW>;
+	};
+
+	// QCA8337 switch
+	switch1: ethernet-switch at 17 {
+		compatible = "qca,qca8337";
+		reg = <17>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 2 {
+				reg = <2>;
+				label = "lan3";
+				phy-handle = <&qca8337_1>;
+			};
+
+			port at 3 {
+				reg = <3>;
+				label = "lan2";
+				phy-handle = <&qca8337_2>;
+			};
+
+			port at 4 {
+				reg = <4>;
+				label = "lan1";
+				phy-handle = <&qca8337_3>;
+			};
+
+			port at 5 {
+				reg = <5>;
+				phy-handle = <&qca8337_4>;
+				phy-mode = "gmii";
+				ethernet = <&dp1>;
+			};
+		};
+	};
+};
+
+&pcie0_phy {
+	status = "okay";
+};
+
+&pcie0 {
+	status = "okay";
+
+	perst-gpios = <&tlmm 15 GPIO_ACTIVE_LOW>;
+
+	bridge at 0,0 {
+		reg = <0x00000000 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		ranges;
+
+		wifi at 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-SPNMX56";
+		};
+	};
+};
+
+&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";
+	};
+};
+
+&wifi0 {
+	// IPQ5018
+	qcom,rproc = <&q6_wcss_pd1>;
+	qcom,ath11k-calibration-variant = "Linksys-SPNMX56";
+	qcom,ath11k-fw-memory-mode = <2>;
+	qcom,bdf-addr = <0x4c400000>;
+
+	status = "okay";
+};
diff --git a/target/linux/qualcommax/image/ipq50xx.mk b/target/linux/qualcommax/image/ipq50xx.mk
index affd5e6345..cf404d49cd 100644
--- a/target/linux/qualcommax/image/ipq50xx.mk
+++ b/target/linux/qualcommax/image/ipq50xx.mk
@@ -29,3 +29,13 @@ define Device/linksys_mx5500
 		ipq-wifi-linksys_mx5500
 endef
 TARGET_DEVICES += linksys_mx5500
+
+define Device/linksys_spnmx56
+	$(call Device/linksys_ipq50xx_mx_base)
+	DEVICE_MODEL := SPNMX56
+	DEVICE_DTS_CONFIG := config at mp03.1
+	DEVICE_PACKAGES := kmod-ath11k-pci \
+		ath11k-firmware-qcn9074 \
+		ipq-wifi-linksys_spnmx56
+endef
+TARGET_DEVICES += linksys_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 35bff6df80..c80b259d27 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
@@ -8,7 +8,8 @@ ipq50xx_setup_interfaces()
 	local board="$1"
 	case $board in
 	linksys,mx2000|\
-	linksys,mx5500)
+	linksys,mx5500|\
+	linksys,spnmx56)
 		ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" "wan"
 		;;
 	esac
@@ -23,7 +24,8 @@ ipq50xx_setup_macs()
 
 	case "$board" in
 	linksys,mx2000|\
-	linksys,mx5500)
+	linksys,mx5500|\
+	linksys,spnmx56)
 		label_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr)
 		lan_mac=$label_mac
 		wan_mac=$label_mac
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 7c8cc99ee3..4da2f2809e 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
@@ -10,7 +10,8 @@ case "$FIRMWARE" in
 "ath11k/IPQ5018/hw1.0/cal-ahb-c000000.wifi.bin")
 	case "$board" in
 	linksys,mx2000|\
-	linksys,mx5500)
+	linksys,mx5500|\
+	linksys,spnmx56)
 		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
@@ -32,7 +33,8 @@ case "$FIRMWARE" in
 	;;
 "ath11k/QCN9074/hw1.0/cal-pci-0001:01:00.0.bin")
 	case "$board" in
-	linksys,mx5500)
+	linksys,mx5500|\
+	linksys,spnmx56)
 		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
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 b570428aef..c49ad8472d 100755
--- a/target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount
+++ b/target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount
@@ -5,7 +5,8 @@ START=99
 boot() {
 	case $(board_name) in
 	linksys,mx2000|\
-	linksys,mx5500)
+	linksys,mx5500|\
+	linksys,spnmx56)
 		mtd resetbc s_env || true
 	;;
 	esac
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 a75b6798d2..5144617f8b 100644
--- a/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh
+++ b/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh
@@ -73,7 +73,8 @@ platform_check_image() {
 platform_do_upgrade() {
 	case "$(board_name)" in
 	linksys,mx2000|\
-	linksys,mx5500)
+	linksys,mx5500|\
+	linksys,spnmx56)
 		remove_oem_ubi_volume rootfs
 		linksys_mx_do_upgrade "$1"
 		;;




More information about the lede-commits mailing list