From 9a7192c08e5a480ed93ee689bc4a71ac2379c7fe Mon Sep 17 00:00:00 2001 From: George Moussalem Date: Thu, 13 Feb 2025 09:54:44 +0400 Subject: [PATCH] qualcommax: ipq50xx: Add support for Linksys MR5500 Add support for Linksys MR5500 (Hydra 6 Pro). Speficiations: * SoC: Qualcomm IPQ5018 (64-bit dual-core ARM Cortex-A53 @ 1.0Ghz) * Memory: Kingston D2516ECMDXGJD (512 MiB) * 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 (4 Ports 10/100/1000 GBASE-T) * Flash: Gigadevice GD5F2GQ5REYIH (256 MiB) * LEDs: 1x multi-color PWM LED 1x blue led for USB (GPIO 19 Active High) * Buttons: 1x WPS (GPIO 27 Active Low) 1x Reset (GPIO 28 Acive Low) 5x ethernet port LEDs (amber for activity & green for link up) * Peripherals: 1x USB2 (powered by GPIO 17 Active Low) support for USB3 will be added in a separate PR * FCC ID: 2AYRA-03734 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:///fwupdate.html. Upgrade firmware using openwrt-qualcommax-ipq50xx-linksys_mr5500-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_mr5500-squashfs-factory.bin kernel and in case of 1: mtd -r -e alt_kernel -n write openwrt-qualcommax-ipq50xx-linksys_mr5500-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_mr5500-squashfs-factory.bin or in case of 1: flash_erase /dev/mtd14 0 0 nandwrite -p /dev/mtd14 openwrt-qualcommax-ipq50xx-linksys_mr5500-squashfs-factory.bin After first boot install firmware on second partition: mtd -r -e kernel -n write openwrt-qualcommax-ipq50xx-linksys_mr5500-squashfs-factory.bin kernel or: mtd -r -e alt_kernel -n write openwrt-qualcommax-ipq50xx-linksys_mr5500-squashfs-factory.bin alt_kernel 3. Back to the OEM firmware. Download firmware from OEM website: MR5500: https://support.linksys.com/kb/article/207-en/ From serial or SSH: fw_printenv boot_part in case of 1: mtd -r -e alt_kernel -n write FW_MR5500_1.1.2.209598_prod.img alt_kernel else in case of 2: mtd -r -e kernel -n write FW_MR5500_1.1.2.209598_prod.img kernel 4. Boot from USB This allows you loading an OpenWrt image into RAM and is meant for recovery scenarios only. Enable loading image from USB in u-boot. From serial or SSH: fw_setenv bootusb 'usb start && usbboot &loadaddr && bootm $loadaddr' fw_setenv bootcmd 'run bootusb; if test $auto_recovery = no; then bootipq; elif test $boot_part = 1; then run bootpart1; else run bootpart2; fi' Copy OpenWrt initramfs image to USB: dd bs=1M if=openwrt-qualcommax-ipq50xx-linksys_mr5500-initramfs-uImage.itb of=/dev/sda Signed-off-by: George Moussalem Link: https://github.com/openwrt/openwrt/pull/17958 Signed-off-by: Robert Marko --- .../uboot-envtools/files/qualcommax_ipq50xx | 1 + package/firmware/ipq-wifi/Makefile | 2 + .../arm64/boot/dts/qcom/ipq5018-mr5500.dts | 387 ++++++++++++++++++ target/linux/qualcommax/image/ipq50xx.mk | 11 + .../ipq50xx/base-files/etc/board.d/01_leds | 28 ++ .../ipq50xx/base-files/etc/board.d/02_network | 3 + .../etc/hotplug.d/firmware/11-ath11k-caldata | 2 + .../ipq50xx/base-files/etc/init.d/bootcount | 1 + .../base-files/lib/upgrade/platform.sh | 1 + .../linux/qualcommax/ipq50xx/config-default | 1 + 10 files changed, 437 insertions(+) create mode 100644 target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mr5500.dts create mode 100644 target/linux/qualcommax/ipq50xx/base-files/etc/board.d/01_leds diff --git a/package/boot/uboot-envtools/files/qualcommax_ipq50xx b/package/boot/uboot-envtools/files/qualcommax_ipq50xx index b63451d627..8c3d2f55be 100644 --- a/package/boot/uboot-envtools/files/qualcommax_ipq50xx +++ b/package/boot/uboot-envtools/files/qualcommax_ipq50xx @@ -8,6 +8,7 @@ touch /etc/config/ubootenv board=$(board_name) case "$board" in +linksys,mr5500|\ linksys,mx2000|\ linksys,mx5500|\ linksys,spnmx56) diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile index deeda4955e..07d5c90c44 100644 --- a/package/firmware/ipq-wifi/Makefile +++ b/package/firmware/ipq-wifi/Makefile @@ -39,6 +39,7 @@ ALLWIFIBOARDS:= \ edgecore_eap102 \ edimax_cax1800 \ linksys_homewrk \ + linksys_mr5500 \ linksys_mr7350 \ linksys_mx2000 \ linksys_mx4200 \ @@ -179,6 +180,7 @@ $(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_homewrk,Linksys HomeWRK)) +$(eval $(call generate-ipq-wifi-package,linksys_mr5500,Linksys MR5500)) $(eval $(call generate-ipq-wifi-package,linksys_mr7350,Linksys MR7350)) $(eval $(call generate-ipq-wifi-package,linksys_mx2000,Linksys MX2000)) $(eval $(call generate-ipq-wifi-package,linksys_mx4200,Linksys MX4200)) diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mr5500.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mr5500.dts new file mode 100644 index 0000000000..6550e22729 --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mr5500.dts @@ -0,0 +1,387 @@ +/dts-v1/; + +#include "ipq5018.dtsi" +#include "ipq5018-mx-base.dtsi" + +/ { + model = "Linksys MR5500"; + compatible = "linksys,mr5500", "qcom,ipq5018"; + + gpio-leds { + compatible = "gpio-leds"; + + usb { + color = ; + function = LED_FUNCTION_USB; + gpios = <&tlmm 19 GPIO_ACTIVE_HIGH>; + trigger-sources = <&usb_port1>; + linux,default-trigger = "usbport"; + }; + }; + + regulator_fixed_5p0: regulator-s0500 { + compatible = "regulator-fixed"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <500000>; + regulator-name = "fixed_5p0"; + gpio = <&tlmm 17 GPIO_ACTIVE_LOW>; + }; +}; + +/* + * =============================================================== + * _______________________ _______________________ + * | IPQ5018 | | QCA8337 | + * | +------+ +--------+ | | +--------+ +------+ | + * | | MAC0 |---| GE Phy | | | | Phy0 |---| MAC1 | | + * | +------+ +--------+ | | +--------+ +------+ | + * | +------+ +--------+ | | +--------+ +------+ | + * | | MAC1 |---| Uniphy |-+-SGMII-+-| SerDes |---| MAC6 | | + * | +------+ +--------+ | | +--------+ +------+ | + * |_______________________| |_______________________| + * + * =============================================================== + */ + +&switch { + status = "okay"; + + switch_mac_mode = ; + + qcom,port_phyinfo { + // MAC0 -> GE Phy + port@0 { + port_id = <1>; + mdiobus = <&mdio0>; + phy_address = <7>; + }; + + // MAC1 ---SGMII---> QCA8337 SerDes + port@1 { + port_id = <2>; + forced-speed = <1000>; + forced-duplex = <1>; + }; + }; +}; + +// MAC1 ---SGMII---> QCA8337 SerDes +&dp2 { + status = "okay"; + + nvmem-cells = <&hw_mac_addr 0>; + nvmem-cell-names = "mac-address"; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&mdio0 { + status = "okay"; +}; + +&mdio1 { + status = "okay"; + + pinctrl-0 = <&mdio1_pins>; + pinctrl-names = "default"; + reset-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>; + + 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 = "lan1"; + phy-handle = <&qca8337_0>; + phy-mode = "internal"; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + + led@1 { + reg = <1>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; + }; + + port@2 { + reg = <2>; + label = "lan2"; + phy-handle = <&qca8337_1>; + phy-mode = "internal"; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + + led@1 { + reg = <1>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; + }; + + port@3 { + reg = <3>; + label = "lan3"; + phy-handle = <&qca8337_2>; + phy-mode = "internal"; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + + led@1 { + reg = <1>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; + }; + + port@4 { + reg = <4>; + label = "lan4"; + phy-handle = <&qca8337_3>; + phy-mode = "internal"; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + + led@1 { + reg = <1>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; + }; + + port@5 { + reg = <5>; + label = "wan"; + phy-handle = <&qca8337_4>; + phy-mode = "internal"; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_WAN; + default-state = "keep"; + }; + + led@1 { + reg = <1>; + color = ; + function = LED_FUNCTION_WAN; + default-state = "keep"; + }; + }; + }; + + port@6 { + reg = <6>; + label = "cpu"; + phy-mode = "sgmii"; + ethernet = <&dp2>; + qca,sgmii-enable-pll; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + // QCA8337 Phy0 -> LAN1 + qca8337_0: ethernet-phy@0 { + reg = <0>; + }; + + // QCA8337 Phy1 -> LAN2 + qca8337_1: ethernet-phy@1 { + reg = <1>; + }; + + // QCA8337 Phy2 -> LAN3 + qca8337_2: ethernet-phy@2 { + reg = <2>; + }; + + // QCA8337 Phy3 -> LAN4 + qca8337_3: ethernet-phy@3 { + reg = <3>; + }; + + // QCA8337 Phy4 -> WAN + qca8337_4: ethernet-phy@4 { + reg = <4>; + }; + }; + }; +}; + +&usbphy0 { + status = "okay"; + + vdd-supply = <®ulator_fixed_5p0>; +}; + +&usb { + status = "okay"; + + vbus-supply = <®ulator_fixed_5p0>; +}; + +&usb_dwc { + address-cells = <1>; + #size-cells = <0>; + dr_mode = "host"; + + usb_port1: port@1 { + reg = <1>; + #trigger-source-cells = <0>; + }; +}; + +&pcie0_phy { + status = "okay"; +}; + +&pcie0 { + 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-MR5500"; + }; + }; +}; + +&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-MR5500"; + 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 cf404d49cd..d6e71f1729 100644 --- a/target/linux/qualcommax/image/ipq50xx.mk +++ b/target/linux/qualcommax/image/ipq50xx.mk @@ -11,6 +11,17 @@ define Device/linksys_ipq50xx_mx_base IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi | linksys-image type=$$$$(DEVICE_MODEL) endef +define Device/linksys_mr5500 + $(call Device/linksys_ipq50xx_mx_base) + DEVICE_MODEL := MR5500 + DEVICE_DTS_CONFIG := config@mp03.1 + DEVICE_PACKAGES := kmod-ath11k-pci \ + ath11k-firmware-qcn9074 \ + ipq-wifi-linksys_mr5500 \ + kmod-usb-ledtrig-usbport +endef +TARGET_DEVICES += linksys_mr5500 + define Device/linksys_mx2000 $(call Device/linksys_ipq50xx_mx_base) DEVICE_MODEL := MX2000 diff --git a/target/linux/qualcommax/ipq50xx/base-files/etc/board.d/01_leds b/target/linux/qualcommax/ipq50xx/base-files/etc/board.d/01_leds new file mode 100644 index 0000000000..3969f233ab --- /dev/null +++ b/target/linux/qualcommax/ipq50xx/base-files/etc/board.d/01_leds @@ -0,0 +1,28 @@ +# +# Copyright (C) 2015 OpenWrt.org +# + +. /lib/functions/uci-defaults.sh + +board_config_update + +board=$(board_name) + +case "$board" in +linksys,mr5500) + ucidef_set_led_netdev "lan1-port-link" "LAN1-PORT-LINK" "qca8k-0.0:00:green:lan" "lan1" "link_10 link_100 link_1000" + ucidef_set_led_netdev "lan1-port-activity" "LAN1-PORT-ACTIVITY" "qca8k-0.0:00:amber:lan" "lan1" "tx rx" + ucidef_set_led_netdev "lan2-port-link" "LAN2-PORT-LINK" "qca8k-0.0:01:green:lan" "lan2" "link_10 link_100 link_1000" + ucidef_set_led_netdev "lan2-port-activity" "LAN2-PORT-ACTIVITY" "qca8k-0.0:01:amber:lan" "lan2" "tx rx" + ucidef_set_led_netdev "lan3-port-link" "LAN3-PORT-LINK" "qca8k-0.0:02:green:lan" "lan3" "link_10 link_100 link_1000" + ucidef_set_led_netdev "lan3-port-activity" "LAN3-PORT-ACTIVITY" "qca8k-0.0:02:amber:lan" "lan3" "tx rx" + ucidef_set_led_netdev "lan4-port-link" "LAN4-PORT-LINK" "qca8k-0.0:03:green:lan" "lan4" "link_10 link_100 link_1000" + ucidef_set_led_netdev "lan4-port-activity" "LAN4-PORT-ACTIVITY" "qca8k-0.0:03:amber:lan" "lan4" "tx rx" + ucidef_set_led_netdev "wan-port-link" "WAN-PORT-LINK" "qca8k-0.0:04:green:wan" "wan" "link_10 link_100 link_1000" + ucidef_set_led_netdev "wan-port-activity" "WAN-PORT-ACTIVITY" "qca8k-0.0:04:amber:wan" "wan" "tx rx" + ;; +esac + +board_config_flush + +exit 0 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 6c8574c474..5679fd93f6 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 @@ -7,6 +7,9 @@ ipq50xx_setup_interfaces() { local board="$1" case $board in + linksys,mr5500) + ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "wan" + ;; linksys,mx2000|\ linksys,mx5500|\ linksys,spnmx56) 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 4da2f2809e..3aa0aa1c30 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 @@ -9,6 +9,7 @@ board=$(board_name) case "$FIRMWARE" in "ath11k/IPQ5018/hw1.0/cal-ahb-c000000.wifi.bin") case "$board" in + linksys,mr5500|\ linksys,mx2000|\ linksys,mx5500|\ linksys,spnmx56) @@ -33,6 +34,7 @@ case "$FIRMWARE" in ;; "ath11k/QCN9074/hw1.0/cal-pci-0001:01:00.0.bin") case "$board" in + linksys,mr5500|\ linksys,mx5500|\ linksys,spnmx56) caldata_extract "0:ART" 0x26800 0x20000 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 c49ad8472d..0e573a1407 100755 --- a/target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount +++ b/target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount @@ -4,6 +4,7 @@ START=99 boot() { case $(board_name) in + linksys,mr5500|\ linksys,mx2000|\ linksys,mx5500|\ linksys,spnmx56) 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 aa71b8992e..3933027114 100644 --- a/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh +++ b/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh @@ -71,6 +71,7 @@ platform_check_image() { platform_do_upgrade() { case "$(board_name)" in + linksys,mr5500|\ linksys,mx2000|\ linksys,mx5500|\ linksys,spnmx56) diff --git a/target/linux/qualcommax/ipq50xx/config-default b/target/linux/qualcommax/ipq50xx/config-default index cc06f0f41f..f920cc9c98 100644 --- a/target/linux/qualcommax/ipq50xx/config-default +++ b/target/linux/qualcommax/ipq50xx/config-default @@ -7,6 +7,7 @@ CONFIG_MTD_SPI_NAND=y CONFIG_NET_DEVLINK=y CONFIG_NET_DSA=y CONFIG_NET_DSA_QCA8K=y +CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT=y CONFIG_NET_DSA_TAG_QCA=y CONFIG_PHYLINK=y CONFIG_PHY_QCOM_M31_USB=y -- 2.30.2