diff --git a/package/boot/uboot-envtools/files/qualcommax_ipq50xx b/package/boot/uboot-envtools/files/qualcommax_ipq50xx new file mode 100644 index 00000000000..97b01df0399 --- /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" "2" + ;; +esac + +config_load ubootenv +config_foreach ubootenv_add_app_config + +exit 0 diff --git a/package/firmware/ipq-wifi/src/board-linksys_mx2000.ipq5018 b/package/firmware/ipq-wifi/src/board-linksys_mx2000.ipq5018 new file mode 100644 index 00000000000..3425c9cea18 Binary files /dev/null and b/package/firmware/ipq-wifi/src/board-linksys_mx2000.ipq5018 differ diff --git a/package/firmware/ipq-wifi/src/board-linksys_mx2000.qcn6122 b/package/firmware/ipq-wifi/src/board-linksys_mx2000.qcn6122 new file mode 100644 index 00000000000..96457e62fd8 Binary files /dev/null and b/package/firmware/ipq-wifi/src/board-linksys_mx2000.qcn6122 differ diff --git a/package/firmware/ipq-wifi/src/board-linksys_mx5500.ipq5018 b/package/firmware/ipq-wifi/src/board-linksys_mx5500.ipq5018 new file mode 100644 index 00000000000..abaf8b6fbfd Binary files /dev/null and b/package/firmware/ipq-wifi/src/board-linksys_mx5500.ipq5018 differ diff --git a/package/firmware/ipq-wifi/src/board-linksys_mx5500.qcn9074 b/package/firmware/ipq-wifi/src/board-linksys_mx5500.qcn9074 new file mode 100644 index 00000000000..7ff8e3d09bf Binary files /dev/null and b/package/firmware/ipq-wifi/src/board-linksys_mx5500.qcn9074 differ diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx-atlas6.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx-atlas6.dtsi new file mode 100644 index 00000000000..62076e10772 --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx-atlas6.dtsi @@ -0,0 +1,554 @@ +#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 { + label = "red:system"; + pwms = <&pwm 3 1250000>; + max-brightness = <255>; + }; + + green { + label = "green:system"; + pwms = <&pwm 0 1250000>; + max-brightness = <255>; + }; + + led_system_blue: blue { + label = "blue:system"; + pwms = <&pwm 1 1250000>; + max-brightness = <255>; + //linux,default-trigger = "default-on"; + }; + }; + + reserved-memory { + tz_appps@4a400000 { + no-map; + reg = <0x0 0x4a400000 0x0 0x400000>; + }; + + q6_mem_regions: q6_mem_regions@4b000000 { + no-map; + reg = <0x0 0x4b000000 0x0 0x3000000>; + }; + + /* from stock DTS: + q6_code_data: q6_code_data@4b000000 { + no-map; + reg = <0x0 0x4b000000 0x0 0x60000>; + }; + + q6_ipq5018_data: q6_ipq5018_data@4c400000 { + no-map; + reg = <0x0 0x4c400000 0x0 0xe00000>; + }; + + q6_m3_region: m3_dump@4d200000 { + no-map; + reg = <0x0 0x4d200000 0x0 0x100000>; + }; + + q6_etr_region: q6_etr_dump@4d300000 { + no-map; + reg = <0x0 0x4d300000 0x0 0x100000>; + }; + + q6_caldb_region: q6_caldb_region@4d400000 { + no-map; + reg = <0x0 0x4d400000 0x0 0x200000>; + }; + + q6_qcn6122_data1: q6_qcn6122_data1@4d600000 { + no-map; + reg = <0x0 0x4d600000 0x0 0x1000000>; + }; + + q6_qcn6122_m3_1: q6_qcn6122_m3_1@4e600000 { + no-map; + reg = <0x0 0x4e600000 0x0 0x100000>; + }; + + q6_qcn6122_etr_1: q6_qcn6122_etr_1@4e700000 { + no-map; + reg = <0x0 0x4e700000 0x0 0x100000>; + }; + + q6_qcn6122_caldb_1: q6_qcn6122_caldb_1@4e800000 { + no-map; + reg = <0x0 0x4e800000 0x0 0x500000>; + }; + + q6_qcn6122_data2: q6_qcn6122_data20@4ed00000 { + no-map; + reg = <0x0 0x4ed00000 0x0 0x1000000>; + }; + + q6_qcn6122_m3_2: q6_qcn6122_m3_2@4fd00000 { + no-map; + reg = <0x0 0x4fd00000 0x0 0x100000>; + }; + + q6_qcn6122_etr_2: q6_qcn6122_etr_2@4fe00000 { + no-map; + reg = <0x0 0x4fe00000 0x0 0x100000>; + }; + + q6_qcn6122_caldb_2: q6_qcn6122_caldb_2@4ff00000 { + no-map; + reg = <0x0 0x4ff00000 0x0 0x500000>; + }; + */ + }; +}; + +&switch { + status = "okay"; + + switch_mac_mode = ; + + qcom,port_phyinfo { + // MAC0 -> GE Phy -> QCA8337 Phy4 + port@0 { + port_id = <1>; + mdiobus = <&mdio0>; + phy_address = <7>; + // status = "disabled"; + }; + + // MAC1 ---SGMII---> QCA8337 SerDes + port@1 { + port_id = <2>; + forced-speed = <1000>; + forced-duplex = <1>; + }; + }; +}; + +// MAC0 -> GE Phy +&dp1 { + /* + * =============================================================== + * _______________________ _______________________ + * | IPQ5018 | | QCA8337 | + * | +------+ +--------+ | | +--------+ +------+ | + * | | MAC0 |---| GE Phy |-+--UTP--+-| Phy4 |---| MAC5 | | + * | +------+ +--------+ | | +--------+ +------+ | + * | +------+ +--------+ | | +--------+ +------+ | + * | | MAC1 |---| Uniphy |-+-SGMII-+-| SerDes |---| MAC0 | | + * | +------+ +--------+ | | +--------+ +------+ | + * |_______________________| |_______________________| + * + * =============================================================== + * + * Current drivers don't support such topology. So dp1 and ge_phy + * are useless. But they can't be disabled dut to qca-ssdk use + * ge_phy to detect IPQ5018 dummy switch. + */ + status = "okay"; +}; + +// MAC1 ---SGMII---> QCA8337 SerDes +&dp2 { + status = "okay"; + phy-mode = "sgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&mdio0 { + status = "okay"; +}; + +// IPQ5018 GE Phy -> QCA8337 Phy1 +&ge_phy { + status = "okay"; +}; + +&mdio1 { + status = "okay"; + + pinctrl-0 = <&mdio1_pins>; + pinctrl-names = "default"; + reset-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>; + + // QCA8337 Phy0 -> IPQ5018 GE Phy + 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@1 { + reg = <1>; + label = "cpu1"; + phy-handle = <&qca8337_0>; + status = "disabled"; + }; + + port@2 { + reg = <2>; + label = "wan"; + phy-handle = <&qca8337_1>; + }; + + port@3 { + reg = <3>; + label = "lan1"; + phy-handle = <&qca8337_2>; + }; + + port@4 { + reg = <4>; + label = "lan2"; + phy-handle = <&qca8337_3>; + }; + + port@5 { + reg = <5>; + label = "lan3"; + 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; + }; + }; + }; + }; +}; + +&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 0x20000>; + 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 0x20000>; + }; + + partition@300000 { + label = "0:APPSBL"; + reg = <0x00300000 0x140000>; + read-only; + }; + + partition@440000 { + compatible = "nvmem-cells"; + label = "0:ART"; + reg = <0x00440000 0x100000>; + #address-cells = <1>; + #size-cells = <1>; + 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 00000000000..a1b2bbd66b3 --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx2000.dts @@ -0,0 +1,120 @@ +/dts-v1/; + +#include "ipq5018.dtsi" +#include "ipq5018-mx-atlas6.dtsi" + +/ { + model = "Linksys MX2000"; + compatible = "linksys,mx2000", "qcom,ipq5018"; +}; + +&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"; +}; \ No newline at end of file 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 00000000000..146ccec51d3 --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-mx5500.dts @@ -0,0 +1,102 @@ +/dts-v1/; + +#include "ipq5018.dtsi" +#include "ipq5018-mx-atlas6.dtsi" + +#include +#include +#include + +/ { + model = "Linksys MX5500"; + compatible = "linksys,mx5500", "qcom,ipq5018"; +}; + +&pcie_x2phy { + status = "okay"; +}; + +&pcie_x2 { + 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"; +}; \ No newline at end of file diff --git a/target/linux/qualcommax/image/ipq50xx.mk b/target/linux/qualcommax/image/ipq50xx.mk index 8b137891791..1f3169161cc 100644 --- a/target/linux/qualcommax/image/ipq50xx.mk +++ b/target/linux/qualcommax/image/ipq50xx.mk @@ -1 +1,32 @@ +define Device/linksys_mx_atlas6 + $(call Device/FitImageLzma) + DEVICE_VENDOR := Linksys + BLOCKSIZE := 128k + PAGESIZE := 2048 + KERNEL_SIZE := 8192k + IMAGE_SIZE := 83968k + NAND_SIZE := 256m + SOC := ipq5018 + UBINIZE_OPTS := -E 5 # EOD marks to "hide" factory sig at EOF + 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_mx_atlas6) + 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_mx_atlas6) + 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 \ No newline at end of file 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 00000000000..bcf606c7568 --- /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 eth1 $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 00000000000..7c8cc99ee3d --- /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 00000000000..b570428aef0 --- /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/linksys.sh b/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/linksys.sh new file mode 100644 index 00000000000..18366fc622a --- /dev/null +++ b/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/linksys.sh @@ -0,0 +1,125 @@ +linksys_get_target_firmware() { + local cur_boot_part mtd_ubi0 + + cur_boot_part="$(/usr/sbin/fw_printenv -n boot_part)" + if [ -z "${cur_boot_part}" ]; then + mtd_ubi0=$(cat /sys/class/ubi/ubi0/mtd_num) + case "$(grep -E "^mtd${mtd_ubi0}:" /proc/mtd | cut -d '"' -f 2)" in + kernel|rootfs) + cur_boot_part=1 + ;; + alt_kernel|alt_rootfs) + cur_boot_part=2 + ;; + esac + >&2 printf "Current boot_part='%s' selected from ubi0/mtd_num='%s'" \ + "${cur_boot_part}" "${mtd_ubi0}" + fi + + # OEM U-Boot for EA6350v3, EA8300 and MR8300; bootcmd= + # if test $auto_recovery = no; + # then bootipq; + # elif test $boot_part = 1; + # then run bootpart1; + # else run bootpart2; + # fi + + case "$cur_boot_part" in + 1) + fw_setenv -s - <<-EOF + boot_part 2 + auto_recovery yes + EOF + printf "alt_kernel" + return + ;; + 2) + fw_setenv -s - <<-EOF + boot_part 1 + auto_recovery yes + EOF + printf "kernel" + return + ;; + *) + return + ;; + esac +} + +linksys_is_factory_image() { + local board=$(board_name) + board=${board##*,} + + # check matching footer signature + tail -c 256 $1 | grep -q -i "\.LINKSYS\.........${board}" +} + +platform_do_upgrade_linksys() { + local magic_long="$(get_magic_long "$1")" + + local rm_oem_fw_vols="squashfs ubifs" # from OEM [alt_]rootfs UBI + local vol + + mkdir -p /var/lock + local part_label="$(linksys_get_target_firmware)" + touch /var/lock/fw_printenv.lock + + if [ -z "$part_label" ]; then + echo "cannot find target partition" + exit 1 + fi + + local target_mtd=$(find_mtd_part "$part_label") + + [ "$magic_long" = "73797375" ] && { + CI_KERNPART="$part_label" + if [ "$part_label" = "kernel" ]; then + CI_UBIPART="rootfs" + else + CI_UBIPART="alt_rootfs" + fi + + local mtdnum="$(find_mtd_index "$CI_UBIPART")" + if [ ! "$mtdnum" ]; then + echo "cannot find ubi mtd partition $CI_UBIPART" + return 1 + fi + + local ubidev="$(nand_find_ubi "$CI_UBIPART")" + if [ ! "$ubidev" ]; then + ubiattach -m "$mtdnum" + sync + ubidev="$(nand_find_ubi "$CI_UBIPART")" + fi + + if [ "$ubidev" ]; then + for vol in $rm_oem_fw_vols; do + ubirmvol "/dev/$ubidev" -N "$vol" 2>/dev/null + done + fi + + # complete std upgrade + if nand_upgrade_tar "$1" ; then + nand_do_upgrade_success + else + nand_do_upgrade_failed + fi + + } + + [ "$magic_long" = "27051956" ] && { + echo "writing \"$1\" image to \"$part_label\"" + get_image "$1" | mtd write - "$part_label" + } + + [ "$magic_long" = "d00dfeed" ] && { + if ! linksys_is_factory_image "$1"; then + echo "factory image doesn't match device" + return 1 + fi + + echo "writing \"$1\" factory image to \"$part_label\"" + get_image "$1" | mtd -e "$part_label" write - "$part_label" + } +} 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 00000000000..b67ab016c6e --- /dev/null +++ b/target/linux/qualcommax/ipq50xx/base-files/lib/upgrade/platform.sh @@ -0,0 +1,21 @@ +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' + +platform_check_image() { + return 0; +} + +platform_do_upgrade() { + case "$(board_name)" in + linksys,mx2000|\ + linksys,mx5500) + platform_do_upgrade_linksys "$1" + ;; + *) + default_do_upgrade "$1" + ;; + esac +}