From: George Moussalem Date: Mon, 7 Oct 2024 12:09:40 +0000 (+0400) Subject: qualcommax: ipq50xx: add support for Linksys MX2000 and MX5500 X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=398f4a97378e2f645badc1aef3d0e9fd76f6665d;p=openwrt%2Fstaging%2Fstintel.git 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 Link: https://github.com/openwrt/openwrt/pull/17182 Signed-off-by: Robert Marko --- diff --git a/package/boot/uboot-envtools/files/qualcommax_ipq50xx b/package/boot/uboot-envtools/files/qualcommax_ipq50xx new file mode 100644 index 0000000000..0e78bb8060 --- /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" + ;; +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 ef67490a5f..408c821035 100644 --- a/package/firmware/ipq-wifi/Makefile +++ b/package/firmware/ipq-wifi/Makefile @@ -39,8 +39,10 @@ ALLWIFIBOARDS:= \ edimax_cax1800 \ linksys_homewrk \ linksys_mr7350 \ + linksys_mx2000 \ linksys_mx4200 \ linksys_mx5300 \ + linksys_mx5500 \ linksys_mx8500 \ linksys_whw03 \ netgear_lbr20 \ @@ -175,8 +177,10 @@ $(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_mr7350,Linksys MR7350)) +$(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/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx-base.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx-base.dtsi new file mode 100644 index 0000000000..57fe5c53a9 --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx-base.dtsi @@ -0,0 +1,325 @@ +#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 { + color = ; + function = LED_FUNCTION_POWER; + pwms = <&pwm 3 1250000>; + max-brightness = <255>; + }; + + green { + color = ; + function = LED_FUNCTION_POWER; + pwms = <&pwm 0 1250000>; + max-brightness = <255>; + }; + + led_system_blue: blue { + color = ; + function = LED_FUNCTION_POWER; + pwms = <&pwm 1 1250000>; + max-brightness = <255>; + }; + }; + + reserved-memory { + q6_mem_regions: q6_mem_regions@4b000000 { + no-map; + reg = <0x0 0x4b000000 0x0 0x3000000>; + }; + }; +}; + +&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 0x80000>; + 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 0x80000>; + }; + + partition@300000 { + label = "0:APPSBL"; + reg = <0x00300000 0x140000>; + read-only; + }; + + partition@440000 { + label = "0:ART"; + reg = <0x00440000 0x100000>; + 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 0000000000..108b26f8d1 --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx2000.dts @@ -0,0 +1,262 @@ +/dts-v1/; + +#include "ipq5018.dtsi" +#include "ipq5018-mx-base.dtsi" + +/ { + model = "Linksys MX2000"; + compatible = "linksys,mx2000", "qcom,ipq5018"; +}; + +/* + * =============================================================== + * _______________________ _______________________ + * | IPQ5018 | | QCA8337 | + * | +------+ +--------+ | | +--------+ +------+ | + * | | MAC0 |---| GE Phy | | | | Phy0 |---| MAC1 | | + * | +------+ +--------+ | | +--------+ +------+ | + * | +------+ +--------+ | | +--------+ +------+ | + * | | MAC1 |---| Uniphy |-+-SGMII-+-| SerDes |---| MAC6 | | + * | +------+ +--------+ | | +--------+ +------+ | + * |_______________________| |_______________________| + * + * =============================================================== + */ + +&switch { + status = "okay"; + + switch_mac_mode = ; + + qcom,port_phyinfo { + // MAC0 -> GE Phy -> QCA8337 Phy4 + 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"; + phy-mode = "sgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&mdio0 { + status = "okay"; +}; + +/* IPQ5018 GE Phy -> Not connected + * needs to be enabled for QSDK to identify the IPQ5018 dummy switch + */ +&ge_phy { + status = "okay"; +}; + +&mdio1 { + status = "okay"; + + pinctrl-0 = <&mdio1_pins>; + pinctrl-names = "default"; + reset-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>; + + // QCA8337 Phy0 not connected + 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@2 { + reg = <2>; + label = "wan"; + phy-handle = <&qca8337_1>; + }; + + port@3 { + reg = <3>; + label = "lan3"; + phy-handle = <&qca8337_2>; + }; + + port@4 { + reg = <4>; + label = "lan2"; + phy-handle = <&qca8337_3>; + }; + + port@5 { + reg = <5>; + label = "lan1"; + 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; + }; + }; + }; + }; +}; + +&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"; + + /* The QCN6102 radio should map to UPD ID 2. Without */ + /* bootargs, the firmware will expect it to be on UPD ID 3 */ + boot-args = < + /* type: */ 0x1 /* PCIE0 */ + /* length: */ 4 + /* UPD ID: */ 2 + /* reset GPIO: */ 15 + /* reserved: */ 0 0>; + + // 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 IRQ_TYPE_NONE>, + <&wcss_smp2p_in 9 IRQ_TYPE_NONE>, + <&wcss_smp2p_in 12 IRQ_TYPE_NONE>, + <&wcss_smp2p_in 11 IRQ_TYPE_NONE>; + 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 5G + q6_wcss_pd2: pd-2 { + firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt"; + + interrupts-extended = + <&wcss_smp2p_in 16 IRQ_TYPE_NONE>, + <&wcss_smp2p_in 17 IRQ_TYPE_NONE>, + <&wcss_smp2p_in 20 IRQ_TYPE_NONE>, + <&wcss_smp2p_in 19 IRQ_TYPE_NONE>; + 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 = "okay"; + }; +}; + +&wifi0 { + // IPQ5018 + qcom,rproc = <&q6_wcss_pd1>; + 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_pd2>; + qcom,userpd-subsys-name = "q6v5_wcss_userpd2"; + qcom,ath11k-calibration-variant = "Linksys-MX2000"; + qcom,ath11k-fw-memory-mode = <2>; + qcom,bdf-addr = <0x4d100000>; + qcom,m3-dump-addr = <0x4df00000>; + + status = "okay"; +}; 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 0000000000..630e8ba310 --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx5500.dts @@ -0,0 +1,240 @@ +/dts-v1/; + +#include "ipq5018.dtsi" +#include "ipq5018-mx-base.dtsi" + +/ { + model = "Linksys MX5500"; + compatible = "linksys,mx5500", "qcom,ipq5018"; +}; + +/* + * =============================================================== + * _______________________ _______________________ + * | IPQ5018 | | QCA8337 | + * | +------+ +--------+ | | +--------+ +------+ | + * | | MAC0 |---| GE Phy | | | | Phy0 |---| MAC1 | | + * | +------+ +--------+ | | +--------+ +------+ | + * | +------+ +--------+ | | +--------+ +------+ | + * | | MAC1 |---| Uniphy |-+-SGMII-+-| SerDes |---| MAC6 | | + * | +------+ +--------+ | | +--------+ +------+ | + * |_______________________| |_______________________| + * + * =============================================================== + */ + +&switch { + status = "okay"; + + switch_mac_mode = ; + + qcom,port_phyinfo { + // MAC0 -> GE Phy -> QCA8337 Phy4 + 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"; + phy-mode = "sgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&mdio0 { + status = "okay"; +}; + +/* IPQ5018 GE Phy -> Not connected + * needs to be enabled for QSDK to identify the IPQ5018 dummy switch + */ +&ge_phy { + status = "okay"; +}; + +&mdio1 { + status = "okay"; + + pinctrl-0 = <&mdio1_pins>; + pinctrl-names = "default"; + reset-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>; + + // QCA8337 Phy0 not connected + 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@2 { + reg = <2>; + label = "wan"; + phy-handle = <&qca8337_1>; + }; + + port@3 { + reg = <3>; + label = "lan3"; + phy-handle = <&qca8337_2>; + }; + + port@4 { + reg = <4>; + label = "lan2"; + phy-handle = <&qca8337_3>; + }; + + port@5 { + reg = <5>; + label = "lan1"; + 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; + }; + }; + }; + }; +}; + +&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-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"; +}; diff --git a/target/linux/qualcommax/image/ipq50xx.mk b/target/linux/qualcommax/image/ipq50xx.mk index e69de29bb2..affd5e6345 100644 --- a/target/linux/qualcommax/image/ipq50xx.mk +++ b/target/linux/qualcommax/image/ipq50xx.mk @@ -0,0 +1,31 @@ +define Device/linksys_ipq50xx_mx_base + $(call Device/FitImageLzma) + DEVICE_VENDOR := Linksys + BLOCKSIZE := 128k + PAGESIZE := 2048 + KERNEL_SIZE := 8192k + IMAGE_SIZE := 83968k + NAND_SIZE := 256m + SOC := ipq5018 + 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_ipq50xx_mx_base) + 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_ipq50xx_mx_base) + 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 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 0000000000..57f11bad84 --- /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 eth0 $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 0000000000..7c8cc99ee3 --- /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-b00a040.wifi1.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 0000000000..b570428aef --- /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/platform.sh b/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh new file mode 100644 index 0000000000..a75b6798d2 --- /dev/null +++ b/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh @@ -0,0 +1,84 @@ +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' + +remove_oem_ubi_volume() { + local oem_volume_name="$1" + local oem_ubivol + local mtdnum + local ubidev + + mtdnum=$(find_mtd_index "$CI_UBIPART") + if [ ! "$mtdnum" ]; then + return + fi + + ubidev=$(nand_find_ubi "$CI_UBIPART") + if [ ! "$ubidev" ]; then + ubiattach --mtdn="$mtdnum" + ubidev=$(nand_find_ubi "$CI_UBIPART") + fi + + if [ "$ubidev" ]; then + oem_ubivol=$(nand_find_volume "$ubidev" "$oem_volume_name") + [ "$oem_ubivol" ] && ubirmvol "/dev/$ubidev" --name="$oem_volume_name" + fi +} + +linksys_mx_do_upgrade() { + local setenv_script="/tmp/fw_env_upgrade" + + CI_UBIPART="rootfs" + boot_part="$(fw_printenv -n boot_part)" + if [ -n "$UPGRADE_OPT_USE_CURR_PART" ]; then + if [ "$boot_part" -eq "2" ]; then + CI_KERNPART="alt_kernel" + CI_UBIPART="alt_rootfs" + fi + else + if [ "$boot_part" -eq "1" ]; then + echo "boot_part 2" >> $setenv_script + CI_KERNPART="alt_kernel" + CI_UBIPART="alt_rootfs" + else + echo "boot_part 1" >> $setenv_script + fi + fi + + boot_part_ready="$(fw_printenv -n boot_part_ready)" + if [ "$boot_part_ready" -ne "3" ]; then + echo "boot_part_ready 3" >> $setenv_script + fi + + auto_recovery="$(fw_printenv -n auto_recovery)" + if [ "$auto_recovery" != "yes" ]; then + echo "auto_recovery yes" >> $setenv_script + fi + + if [ -f "$setenv_script" ]; then + fw_setenv -s $setenv_script || { + echo "failed to update U-Boot environment" + return 1 + } + fi + nand_do_upgrade "$1" +} + +platform_check_image() { + return 0; +} + +platform_do_upgrade() { + case "$(board_name)" in + linksys,mx2000|\ + linksys,mx5500) + remove_oem_ubi_volume rootfs + linksys_mx_do_upgrade "$1" + ;; + *) + default_do_upgrade "$1" + ;; + esac +}