qualcommax: ipq50xx: Add support for Linksys MR5500
authorGeorge Moussalem <george.moussalem@outlook.com>
Thu, 13 Feb 2025 05:54:44 +0000 (09:54 +0400)
committerRobert Marko <robimarko@gmail.com>
Sun, 2 Mar 2025 10:42:48 +0000 (11:42 +0100)
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://<router IP>/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 <george.moussalem@outlook.com>
Link: https://github.com/openwrt/openwrt/pull/17958
Signed-off-by: Robert Marko <robimarko@gmail.com>
package/boot/uboot-envtools/files/qualcommax_ipq50xx
package/firmware/ipq-wifi/Makefile
target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mr5500.dts [new file with mode: 0644]
target/linux/qualcommax/image/ipq50xx.mk
target/linux/qualcommax/ipq50xx/base-files/etc/board.d/01_leds [new file with mode: 0644]
target/linux/qualcommax/ipq50xx/base-files/etc/board.d/02_network
target/linux/qualcommax/ipq50xx/base-files/etc/hotplug.d/firmware/11-ath11k-caldata
target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount
target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh
target/linux/qualcommax/ipq50xx/config-default

index b63451d627f74e9b2e67688c8a49d449b344b691..8c3d2f55be0601bb24f1796fce756ca31cca233d 100644 (file)
@@ -8,6 +8,7 @@ touch /etc/config/ubootenv
 board=$(board_name)
 
 case "$board" in
+linksys,mr5500|\
 linksys,mx2000|\
 linksys,mx5500|\
 linksys,spnmx56)
index deeda4955e552c50fbe411e16533d319d9ff44ee..07d5c90c4415588fcf7a8b49ba28db51d7d9ec4a 100644 (file)
@@ -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 (file)
index 0000000..6550e22
--- /dev/null
@@ -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 = <LED_COLOR_ID_BLUE>;
+                       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 = <MAC_MODE_SGMII_CHANNEL0>;
+
+       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 = <LED_COLOR_ID_GREEN>;
+                                               function = LED_FUNCTION_LAN;
+                                               default-state = "keep";
+                                       };
+
+                                       led@1 {
+                                               reg = <1>;
+                                               color = <LED_COLOR_ID_AMBER>;
+                                               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 = <LED_COLOR_ID_GREEN>;
+                                               function = LED_FUNCTION_LAN;
+                                               default-state = "keep";
+                                       };
+
+                                       led@1 {
+                                               reg = <1>;
+                                               color = <LED_COLOR_ID_AMBER>;
+                                               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 = <LED_COLOR_ID_GREEN>;
+                                               function = LED_FUNCTION_LAN;
+                                               default-state = "keep";
+                                       };
+
+                                       led@1 {
+                                               reg = <1>;
+                                               color = <LED_COLOR_ID_AMBER>;
+                                               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 = <LED_COLOR_ID_GREEN>;
+                                               function = LED_FUNCTION_LAN;
+                                               default-state = "keep";
+                                       };
+
+                                       led@1 {
+                                               reg = <1>;
+                                               color = <LED_COLOR_ID_AMBER>;
+                                               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 = <LED_COLOR_ID_GREEN>;
+                                               function = LED_FUNCTION_WAN;
+                                               default-state = "keep";
+                                       };
+
+                                       led@1 {
+                                               reg = <1>;
+                                               color = <LED_COLOR_ID_AMBER>;
+                                               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 = <&regulator_fixed_5p0>;
+};
+
+&usb {
+       status = "okay";
+
+       vbus-supply = <&regulator_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";
+};
index cf404d49cdec36da5c558916df39e98ae2dbefcc..d6e71f1729cfed528c8a514c796a3df80eccd58d 100644 (file)
@@ -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 (file)
index 0000000..3969f23
--- /dev/null
@@ -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
index 6c8574c474362b2177a8e699d4901ca3756113ae..5679fd93f635a74b69643af3d48065ec60c4c842 100644 (file)
@@ -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)
index 4da2f2809ef9c69a1f36ae06ef9c7c9fe2f0fc06..3aa0aa1c30547c6b8f1c4d9d26c583d0e9c82f9e 100644 (file)
@@ -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
index c49ad8472de9e7bbe823f421844cd8a63037fcd8..0e573a140727dd9e431b3f0a9d0a094d2c465d23 100755 (executable)
@@ -4,6 +4,7 @@ START=99
 
 boot() {
        case $(board_name) in
+       linksys,mr5500|\
        linksys,mx2000|\
        linksys,mx5500|\
        linksys,spnmx56)
index aa71b8992e7e52c0b8df68a1df4fb24544f65545..3933027114d63a801fdf330fa1fa66e53af19cbc 100644 (file)
@@ -71,6 +71,7 @@ platform_check_image() {
 
 platform_do_upgrade() {
        case "$(board_name)" in
+       linksys,mr5500|\
        linksys,mx2000|\
        linksys,mx5500|\
        linksys,spnmx56)
index cc06f0f41f6fb9b54154c3512ecbb65442aa6e7b..f920cc9c98fd8caf5603b347aa7314ca6a6a9e18 100644 (file)
@@ -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