diff --git a/.github/filters.yml b/.github/filters.yml index 6e7badaa..1635b172 100644 --- a/.github/filters.yml +++ b/.github/filters.yml @@ -47,6 +47,15 @@ "targets/targets.mk", "targets/bcm27xx.inc" ], + "ipq40xx-chromium": [ + "targets/ipq40xx-chromium", + "modules", + "Makefile", + "patches/**", + "scripts/**", + "targets/generic", + "targets/targets.mk" + ], "ipq40xx-generic": [ "targets/ipq40xx-generic", "modules", diff --git a/patches/openwrt/0011-ipq40xx-Support-Chromium-OS-image-type-creation.patch b/patches/openwrt/0011-ipq40xx-Support-Chromium-OS-image-type-creation.patch new file mode 100644 index 00000000..d74541ed --- /dev/null +++ b/patches/openwrt/0011-ipq40xx-Support-Chromium-OS-image-type-creation.patch @@ -0,0 +1,76 @@ +From: Brian Norris +Date: Sat, 13 Jun 2020 20:12:18 -0700 +Subject: ipq40xx: Support Chromium OS image-type creation + +See firmware-utils.git commits [1], which implemented the cros-vbutil +verified-boot payload-packing tool, and extended ptgen for the CrOS +kernel partition type. With these, it's now possible to package kernel + +rootfs to make disk images that can boot a Chrome OS-based system (e.g., +Chromebooks, or even a few AP models). + +Regarding PARTUUID= changes: Chromium bootloaders work well with a +partition number offset (i.e., relative to the kernel partition), so +we'll be using a slightly different root UUID line. + +NB: I've made this support specific to ip40xx for now, because I only +plan to support an IPQ4019-based AP that uses a Chromium-based +bootloader, but this image format can be used for essentially any +Chromebook, as well as the Google OnHub, a prior Chromium-based AP using +an IPQ8064 chipset. + +[1] +ptgen: add Chromium OS kernel partition support +https://git.openwrt.org/?p=project/firmware-utils.git;a=commit;h=6c95945b5de973026dc6f52eb088d0943efa96bb + +cros-vbutil: add Chrome OS vboot kernel-signing utility +https://git.openwrt.org/?p=project/firmware-utils.git;a=commit;h=8e7274e02fdc6f2cb61b415d6e5b2e1c7e977aa1 + +Signed-off-by: Brian Norris +(cherry picked from commit 17b05045bd82f04a8839666ec0fe43a5041d77c7) +Signed-off-by: Jan-Niklas Burfeind + +diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh +index 24ff77a8b3101e0ad1ee0f4b46ff626ecb1ce0f5..5af061f6a43990afea92f8eacd865fe5249d8300 100644 +--- a/package/base-files/files/lib/upgrade/common.sh ++++ b/package/base-files/files/lib/upgrade/common.sh +@@ -155,9 +155,11 @@ export_bootdevice() { + fi + done + ;; ++ PARTUUID=????????-????-????-????-??????????0?/PARTNROFF=1 | \ + PARTUUID=????????-????-????-????-??????????02) + uuid="${rootpart#PARTUUID=}" +- uuid="${uuid%02}00" ++ uuid="${uuid%/PARTNROFF=1}" ++ uuid="${uuid%0?}00" + for disk in $(find /dev -type b); do + set -- $(dd if=$disk bs=1 skip=568 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"') + if [ "$4$3$2$1-$6$5-$8$7-$9" = "$uuid" ]; then +diff --git a/target/linux/ipq40xx/image/chromium.mk b/target/linux/ipq40xx/image/chromium.mk +new file mode 100644 +index 0000000000000000000000000000000000000000..15d4c1a077e816056552261d09f64acf89530154 +--- /dev/null ++++ b/target/linux/ipq40xx/image/chromium.mk +@@ -0,0 +1,22 @@ ++define Build/cros-gpt ++ cp $@ $@.tmp 2>/dev/null || true ++ ptgen -o $@.tmp -g \ ++ -T cros_kernel -N kernel -p $(CONFIG_TARGET_KERNEL_PARTSIZE)m \ ++ -N rootfs -p $(CONFIG_TARGET_ROOTFS_PARTSIZE)m ++ cat $@.tmp >> $@ ++ rm $@.tmp ++endef ++ ++define Build/append-kernel-part ++ dd if=$(IMAGE_KERNEL) bs=$(CONFIG_TARGET_KERNEL_PARTSIZE)M conv=sync >> $@ ++endef ++ ++# NB: Chrome OS bootloaders replace the '%U' in command lines with the UUID of ++# the kernel partition it chooses to boot from. This gives a flexible way to ++# consistently build and sign kernels that always use the subsequent ++# (PARTNROFF=1) partition as their rootfs. ++define Build/cros-vboot ++ $(STAGING_DIR_HOST)/bin/cros-vbutil \ ++ -k $@ -c "root=PARTUUID=%U/PARTNROFF=1" -o $@.new ++ @mv $@.new $@ ++endef diff --git a/patches/openwrt/0012-ipq40xx-Add-subtarget-for-Google-WiFi-Gale.patch b/patches/openwrt/0012-ipq40xx-Add-subtarget-for-Google-WiFi-Gale.patch new file mode 100644 index 00000000..c30ce369 --- /dev/null +++ b/patches/openwrt/0012-ipq40xx-Add-subtarget-for-Google-WiFi-Gale.patch @@ -0,0 +1,645 @@ +From: Brian Norris +Date: Mon, 25 May 2020 14:50:20 -0700 +Subject: ipq40xx: Add subtarget for Google WiFi (Gale) + +Google WiFi (codename: Gale) is an IPQ4019-based AP, with 2 Ethernet +ports, 2x2 2.4+5GHz WiFi, 512 MB RAM, 4 GB eMMC, and a USB type C port. +In its stock configuration, it runs a Chromium OS-based system, but you +wouldn't know it, since you can only manage it via a "cloud" + +mobile-app system. + +The "v2" label is coded into the bootloader, which prefers the +"google,gale-v2" compatible string. I believe "v1" must have been +pre-release hardware. + +Note: this is *not* the Google Nest WiFi, released in 2019. + +I include "factory.bin" support, where we generate a GPT-based disk +image with 2 partitions -- a kernel partition (using the custom "Chrome +OS kernel" GUID type) and a root filesystem partition. See below for +flashing instructions. + +Sysupgrade is supported via recent emmc_do_upgrade() helper. + +This is a subtarget because it enables different features +(FEATURES=boot-part rootfs-part) whose configurations don't make sense +in the "generic" target, and because it builds in a few USB drivers, +which are necessary for installation (installation is performed by +booting from USB storage, and so these drivers cannot be built as +modules, since we need to load modules from USB storage). + +Flashing instructions +===================== + +Documented here: +https://openwrt.org/inbox/toh/google/google_wifi + +Note this requires booting from USB storage. + +Features +======== + +I've tested: + + * Ethernet, both WAN and LAN ports + * eMMC + * USB-C (hub, power-delivery, peripherals) + * LED0 (R/G/B) + * WiFi (limited testing) + * SPI flash + * Serial console: once in developer mode, console can be accessed via + the USB-C port with SuzyQable, or other similar "Closed Case + Debugging" tools: + https://chromium.googlesource.com/chromiumos/third_party/hdctools/+/master/docs/ccd.md#suzyq-suzyqable + * Sysupgrade + +Not tested: + + * TPM + +Known not working: + + * Reboot: this requires some additional TrustZone / SCM + configuration to disable Qualcomm's SDI. I have a proposal upstream, + and based on IRC chats, this might be acceptable with additional DT + logic: + [RFC PATCH] firmware: qcom_scm: disable SDI at boot + https://lore.kernel.org/linux-arm-msm/20200721080054.2803881-1-computersforpeace@gmail.com/ + * SMP: enabling secondary CPUs doesn't currently work using the stock + bootloader, as the qcom_scm driver assumes newer features than this + TrustZone firmware has. I posted notes here: + [RFC] qcom_scm: IPQ4019 firmware does not support atomic API? + https://lore.kernel.org/linux-arm-msm/20200913201608.GA3162100@bDebian/ + * There's a single external button, and a few useful internal GPIO + switches. I haven't hooked them up. + +The first two are fixed with subsequent commits. + +Additional notes +================ + +Much of the DTS is pulled from the Chrome OS kernel 3.18 branch, which +the manufacturer image uses. + +Note: the manufacturer bootloader knows how to patch in calibration data +via the wifi{0,1} aliases in the DTB, so while these properties aren't +present in the DTS, they are available at runtime: + + # ls -l +/sys/firmware/devicetree/base/soc/wifi@a*/qcom,ath10k-pre-calibration-data + -r--r--r-- 1 root root 12064 Jul 15 19:11 /sys/firmware/devicetree/base/soc/wifi@a000000/qcom,ath10k-pre-calibration-data + -r--r--r-- 1 root root 12064 Jul 15 19:11 /sys/firmware/devicetree/base/soc/wifi@a800000/qcom,ath10k-pre-calibration-data + +Ethernet MAC addresses are similarly patched in via the ethernet{0,1} aliases. + +Signed-off-by: Brian Norris +(updated 901 - x1pro moved in the process) +Signed-off-by: Christian Lamparter +(cherry picked from commit f1c041e34f9742fcdd0c8c65f69888d3ec580541) +Signed-off-by: Jan-Niklas Burfeind +(updated 901 - fixed offset, after missing drop commit) + +diff --git a/target/linux/ipq40xx/Makefile b/target/linux/ipq40xx/Makefile +index b704e1b54efea35873661db9cb947412a54c41c7..6051c8294576a64d1ee80247addfedd4937758ff 100644 +--- a/target/linux/ipq40xx/Makefile ++++ b/target/linux/ipq40xx/Makefile +@@ -6,7 +6,7 @@ BOARDNAME:=Qualcomm Atheros IPQ40XX + FEATURES:=squashfs fpu ramdisk nand + CPU_TYPE:=cortex-a7 + CPU_SUBTYPE:=neon-vfpv4 +-SUBTARGETS:=generic mikrotik ++SUBTARGETS:=generic chromium mikrotik + + KERNEL_PATCHVER:=5.10 + KERNEL_TESTING_PATCHVER:=5.10 +diff --git a/target/linux/ipq40xx/base-files/etc/board.d/02_network b/target/linux/ipq40xx/base-files/etc/board.d/02_network +index a38d35a10dcf30e19e2e29a1a3ea1a6f4539afdb..5072e709421a403c4600cf35e81e8bea407149e8 100644 +--- a/target/linux/ipq40xx/base-files/etc/board.d/02_network ++++ b/target/linux/ipq40xx/base-files/etc/board.d/02_network +@@ -46,6 +46,7 @@ ipq40xx_setup_interfaces() + cilab,meshpoint-one|\ + edgecore,ecw5211|\ + edgecore,oap100|\ ++ google,wifi|\ + openmesh,a42|\ + openmesh,a62) + ucidef_set_interfaces_lan_wan "eth1" "eth0" +diff --git a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh +index e9c17e5b01e6fa86b1d8bd070d95c51d822a1997..f02500a86c41ad1df371a0fcbd4c7ab80f033c0e 100644 +--- a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh ++++ b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh +@@ -153,6 +153,13 @@ platform_do_upgrade() { + compex,wpj419) + nand_do_upgrade "$1" + ;; ++ google,wifi) ++ export_bootdevice ++ export_partdevice CI_ROOTDEV 0 ++ CI_KERNPART="kernel" ++ CI_ROOTPART="rootfs" ++ emmc_do_upgrade "$1" ++ ;; + linksys,ea6350v3 |\ + linksys,ea8300 |\ + linksys,mr8300) +@@ -202,7 +209,8 @@ platform_do_upgrade() { + + platform_copy_config() { + case "$(board_name)" in +- glinet,gl-b2200) ++ glinet,gl-b2200 |\ ++ google,wifi) + emmc_copy_config + ;; + esac +diff --git a/target/linux/ipq40xx/chromium/config-default b/target/linux/ipq40xx/chromium/config-default +new file mode 100644 +index 0000000000000000000000000000000000000000..83a42dfb663b045312eef331294a58d98ff3eb84 +--- /dev/null ++++ b/target/linux/ipq40xx/chromium/config-default +@@ -0,0 +1,10 @@ ++CONFIG_BLK_DEV_SD=y ++CONFIG_BLK_SCSI_REQUEST=y ++CONFIG_SCSI=y ++CONFIG_SG_POOL=y ++CONFIG_USB_DWC3=y ++CONFIG_USB_DWC3_HOST=y ++CONFIG_USB_DWC3_QCOM=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_PLATFORM=y +diff --git a/target/linux/ipq40xx/chromium/target.mk b/target/linux/ipq40xx/chromium/target.mk +new file mode 100644 +index 0000000000000000000000000000000000000000..3983a9281a5d20eccdba636c02c9622333d38699 +--- /dev/null ++++ b/target/linux/ipq40xx/chromium/target.mk +@@ -0,0 +1,2 @@ ++BOARDNAME:=Google Chromium ++FEATURES += emmc boot-part rootfs-part +diff --git a/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-wifi.dts b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-wifi.dts +new file mode 100644 +index 0000000000000000000000000000000000000000..9448e5145e29c39d4f7bfc2b94a745b2ccc1cf2d +--- /dev/null ++++ b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-wifi.dts +@@ -0,0 +1,413 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2016, 2018 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2016 Google, Inc ++ */ ++ ++#include "qcom-ipq4019.dtsi" ++#include ++#include ++#include ++ ++/ { ++ model = "Google WiFi (Gale)"; ++ compatible = "google,wifi", "google,gale-v2", "qcom,ipq4019"; ++ ++ chosen { ++ /* ++ * rootwait: in case we're booting from slow/async USB storage. ++ */ ++ bootargs-append = " rootwait"; ++ stdout-path = &blsp1_uart1; ++ }; ++ ++ memory { ++ device_type = "memory"; ++ reg = <0x80000000 0x20000000>; /* 512MB */ ++ }; ++ ++ soc { ++ ess-switch@c000000 { ++ status = "okay"; ++ }; ++ ++ edma@c080000 { ++ status = "okay"; ++ }; ++ ++ ess-psgmii@98000 { ++ status = "okay"; ++ }; ++ }; ++}; ++ ++&tlmm { ++ fw_pinmux { ++ wp { ++ pins = "gpio53"; ++ output-low; ++ }; ++ recovery { ++ pins = "gpio57"; ++ bias-none; ++ }; ++ developer { ++ pins = "gpio41"; ++ bias-none; ++ }; ++ }; ++ ++ reset802_15_4 { ++ pins = "gpio60"; ++ }; ++ ++ led_reset { ++ pins = "gpio22"; ++ output-high; ++ }; ++ ++ sys_reset { ++ pins = "gpio19"; ++ output-high; ++ }; ++ ++ rx_active { ++ pins = "gpio43"; ++ bias-pull,down; ++ }; ++ ++ spi_0_pins: spi_0_pinmux { ++ pinmux { ++ function = "blsp_spi0"; ++ pins = "gpio13", "gpio14","gpio15"; ++ }; ++ pinmux_cs { ++ function = "gpio"; ++ pins = "gpio12"; ++ }; ++ pinconf { ++ pins = "gpio13", "gpio14","gpio15"; ++ drive-strength = <12>; ++ bias-disable; ++ }; ++ pinconf_cs { ++ pins = "gpio12"; ++ drive-strength = <2>; ++ bias-disable; ++ output-high; ++ }; ++ }; ++ ++ spi_1_pins: spi_1_pinmux { ++ pinmux { ++ function = "blsp_spi1"; ++ pins = "gpio44", "gpio46","gpio47"; ++ }; ++ pinmux_cs { ++ function = "gpio"; ++ pins = "gpio45"; ++ }; ++ pinconf { ++ pins = "gpio44", "gpio46","gpio47"; ++ drive-strength = <12>; ++ bias-disable; ++ }; ++ pinconf_cs { ++ pins = "gpio45"; ++ drive-strength = <2>; ++ bias-disable; ++ output-high; ++ }; ++ }; ++ ++ serial_0_pins: serial0_pinmux { ++ mux { ++ pins = "gpio16", "gpio17"; ++ function = "blsp_uart0"; ++ bias-disable; ++ }; ++ }; ++ ++ serial_1_pins: serial1_pinmux { ++ mux { ++ pins = "gpio8", "gpio9", "gpio10", "gpio11"; ++ function = "blsp_uart1"; ++ bias-disable; ++ }; ++ }; ++ ++ i2c_0_pins: i2c_0_pinmux { ++ mux { ++ pins = "gpio20", "gpio21"; ++ function = "blsp_i2c0"; ++ drive-open-drain; ++ }; ++ }; ++ ++ i2c_1_pins: i2c_1_pinmux { ++ mux { ++ pins = "gpio34", "gpio35"; ++ function = "blsp_i2c1"; ++ drive-open-drain; ++ }; ++ }; ++ ++ sd_0_pins: sd_0_pinmux { ++ sd0 { ++ pins = "gpio23", "gpio24", "gpio25", "gpio26", "gpio29", "gpio30", "gpio31", "gpio32"; ++ function = "sdio"; ++ drive-strength = <10>; ++ bias-pull-up; ++ pull-up-res = <0>; ++ }; ++ sdclk { ++ pins = "gpio27"; ++ function = "sdio"; ++ drive-strength = <2>; ++ bias-pull-up; ++ pull-up-res = <0>; ++ }; ++ sdcmd { ++ pins = "gpio28"; ++ function = "sdio"; ++ drive-strength = <10>; ++ bias-pull-up; ++ pull-up-res = <0>; ++ }; ++ }; ++ ++ mdio_pins: mdio_pinmux { ++ mux_1 { ++ pins = "gpio6"; ++ function = "mdio"; ++ bias-disable; ++ }; ++ mux_2 { ++ pins = "gpio7"; ++ function = "mdc"; ++ bias-disable; ++ }; ++ mux_3 { ++ pins = "gpio40"; ++ function = "gpio"; ++ bias-disable; ++ output-high; ++ }; ++ }; ++ ++ wifi1_1_pins: wifi2_pinmux { ++ mux { ++ pins = "gpio58"; ++ output-low; ++ }; ++ }; ++}; ++ ++&blsp_dma { ++ status = "okay"; ++}; ++ ++&blsp1_i2c3 { ++ pinctrl-0 = <&i2c_0_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ tpm@20 { ++ compatible = "infineon,slb9645tt"; ++ reg = <0x20>; ++ powered-while-suspended; ++ }; ++}; ++ ++&blsp1_i2c4 { ++ pinctrl-0 = <&i2c_1_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ led-controller@32 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "national,lp5523"; ++ reg = <0x32>; ++ clock-mode = /bits/ 8 <1>; ++ ++#if 1 ++ led@0 { ++ reg = <0>; ++ chan-name = "LED0_Red"; ++ led-cur = /bits/ 8 <0x64>; ++ max-cur = /bits/ 8 <0x78>; ++ color = ; ++ }; ++ ++ led@1 { ++ reg = <1>; ++ chan-name = "LED0_Green"; ++ led-cur = /bits/ 8 <0x64>; ++ max-cur = /bits/ 8 <0x78>; ++ color = ; ++ }; ++ ++ led@2 { ++ reg = <2>; ++ chan-name = "LED0_Blue"; ++ led-cur = /bits/ 8 <0x64>; ++ max-cur = /bits/ 8 <0x78>; ++ color = ; ++ }; ++#else ++ /* ++ * openwrt isn't ready to handle multi-intensity leds yet ++ * # echo 255 255 255 > /sys/class/leds/tricolor/multi_intensity ++ * # echo 255 > /sys/class/leds/tricolor/brightness ++ */ ++ multi-led@2 { ++ reg = <2>; ++ color = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ led@0 { ++ reg = <0>; ++ chan-name = "tricolor"; ++ led-cur = /bits/ 8 <0x64>; ++ max-cur = /bits/ 8 <0x78>; ++ color = ; ++ }; ++ ++ led@1 { ++ reg = <1>; ++ chan-name = "tricolor"; ++ led-cur = /bits/ 8 <0x64>; ++ max-cur = /bits/ 8 <0x78>; ++ color = ; ++ }; ++ ++ led@2 { ++ reg = <2>; ++ chan-name = "tricolor"; ++ led-cur = /bits/ 8 <0x64>; ++ max-cur = /bits/ 8 <0x78>; ++ color = ; ++ }; ++ }; ++#endif ++ }; ++}; ++ ++&blsp1_spi1 { ++ pinctrl-0 = <&spi_0_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ cs-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>; ++ ++ flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <24000000>; ++ }; ++}; ++ ++&blsp1_spi2 { ++ pinctrl-0 = <&spi_1_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ cs-gpios = <&tlmm 45 GPIO_ACTIVE_HIGH>; ++ ++ /* ++ * This "spidev" was included in the manufacturer device tree. I ++ * suspect it's the (unused; and removed from later HW spins) Zigbee ++ * radio -- SiliconLabs EM3581 Zigbee? There's no driver or binding for ++ * this at the moment. ++ */ ++ spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; ++ spi-max-frequency = <24000000>; ++ }; ++}; ++ ++&blsp1_uart1 { ++ pinctrl-0 = <&serial_0_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ ++&blsp1_uart2 { ++ pinctrl-0 = <&serial_1_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ ++&gmac0 { ++ qcom,phy_mdio_addr = <4>; ++ qcom,poll_required = <1>; ++ qcom,forced_speed = <1000>; ++ qcom,forced_duplex = <1>; ++ vlan_tag = <2 0x20>; ++}; ++ ++&gmac1 { ++ qcom,phy_mdio_addr = <3>; ++ qcom,forced_duplex = <1>; ++ vlan_tag = <1 0x10>; ++}; ++ ++&mdio { ++ status = "okay"; ++ pinctrl-0 = <&mdio_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&prng { ++ status = "okay"; ++}; ++ ++&sdhci { ++ status = "okay"; ++ pinctrl-0 = <&sd_0_pins>; ++ pinctrl-names = "default"; ++ clock-frequency = <192000000>; ++ vqmmc-supply = <&vqmmc>; ++ non-removable; ++}; ++ ++&usb2 { ++ status = "okay"; ++}; ++ ++&usb2_hs_phy { ++ status = "okay"; ++}; ++ ++&usb3 { ++ status = "okay"; ++}; ++ ++&usb3_ss_phy { ++ status = "okay"; ++}; ++ ++&usb3_hs_phy { ++ status = "okay"; ++}; ++ ++&vqmmc { ++ status = "okay"; ++}; ++ ++&watchdog { ++ status = "okay"; ++}; ++ ++&wifi0 { ++ status = "okay"; ++ qcom,ath10k-calibration-variant = "GO_GALE"; ++}; ++ ++&wifi1 { ++ status = "okay"; ++ pinctrl-0 = <&wifi1_1_pins>; ++ pinctrl-names = "default"; ++ qcom,ath10k-calibration-variant = "GO_GALE"; ++}; +diff --git a/target/linux/ipq40xx/image/chromium.mk b/target/linux/ipq40xx/image/chromium.mk +index 15d4c1a077e816056552261d09f64acf89530154..2c8457dcfbbb042e6bda08ae946e1219af4c4ffc 100644 +--- a/target/linux/ipq40xx/image/chromium.mk ++++ b/target/linux/ipq40xx/image/chromium.mk +@@ -20,3 +20,17 @@ define Build/cros-vboot + -k $@ -c "root=PARTUUID=%U/PARTNROFF=1" -o $@.new + @mv $@.new $@ + endef ++ ++define Device/google_wifi ++ DEVICE_VENDOR := Google ++ DEVICE_MODEL := WiFi (Gale) ++ SOC := qcom-ipq4019 ++ KERNEL_SUFFIX := -fit-zImage.itb.vboot ++ KERNEL = kernel-bin | fit none $$(DTS_DIR)/$$(DEVICE_DTS).dtb | cros-vboot ++ KERNEL_NAME := zImage ++ IMAGES += factory.bin ++ IMAGE/factory.bin := cros-gpt | append-kernel-part | append-rootfs ++ DEVICE_PACKAGES := ipq-wifi-google_wifi partx-utils mkf2fs e2fsprogs \ ++ kmod-fs-ext4 kmod-fs-f2fs kmod-google-firmware ++endef ++TARGET_DEVICES += google_wifi +diff --git a/target/linux/ipq40xx/patches-5.10/901-arm-boot-add-dts-files.patch b/target/linux/ipq40xx/patches-5.10/901-arm-boot-add-dts-files.patch +index c51586a2329cd658321359cbc93817c5392fee7b..c30bc011d7deb1fd5af49cc89344d9ce10f75ffe 100644 +--- a/target/linux/ipq40xx/patches-5.10/901-arm-boot-add-dts-files.patch ++++ b/target/linux/ipq40xx/patches-5.10/901-arm-boot-add-dts-files.patch +@@ -10,7 +10,7 @@ Signed-off-by: John Crispin + + --- a/arch/arm/boot/dts/Makefile + +++ b/arch/arm/boot/dts/Makefile +-@@ -904,11 +904,76 @@ dtb-$(CONFIG_ARCH_QCOM) += \ ++@@ -904,11 +904,77 @@ dtb-$(CONFIG_ARCH_QCOM) += \ + qcom-apq8074-dragonboard.dtb \ + qcom-apq8084-ifc6540.dtb \ + qcom-apq8084-mtp.dtb \ +@@ -72,10 +72,11 @@ Signed-off-by: John Crispin + + qcom-ipq4019-rtl30vw.dtb \ + + qcom-ipq4019-srr60.dtb \ + + qcom-ipq4019-srs60.dtb \ +-+ qcom-ipq4019-x1pro.dtb \ + + qcom-ipq4019-u4019-32m.dtb \ +++ qcom-ipq4019-wifi.dtb \ + + qcom-ipq4019-wpj419.dtb \ + + qcom-ipq4019-wtr-m2133hp.dtb \ +++ qcom-ipq4019-x1pro.dtb \ + + qcom-ipq4028-wpj428.dtb \ + + qcom-ipq4029-ap-303.dtb \ + + qcom-ipq4029-ap-303h.dtb \ diff --git a/patches/openwrt/0013-firmware-ipq-wifi-Add-Google-Wifi-board-2.bin.patch b/patches/openwrt/0013-firmware-ipq-wifi-Add-Google-Wifi-board-2.bin.patch new file mode 100644 index 00000000..abbd9ceb --- /dev/null +++ b/patches/openwrt/0013-firmware-ipq-wifi-Add-Google-Wifi-board-2.bin.patch @@ -0,0 +1,154 @@ +From: Brian Norris +Date: Tue, 22 Feb 2022 00:00:29 -0800 +Subject: firmware/ipq-wifi: Add Google Wifi board-2.bin + +From a manufacturer's image (version R89-13729.57.27), with appopriate +',variant=' appended to the board names: + + $ .../qca-swiss-army-knife/tools/scripts/ath10k/ath10k-bdencoder \ + -i ./board-google_wifi.qca4019 + FileSize: 48596 + FileCRC32: 3966df5d + FileMD5: d54161b0fb9e93691c4272649c37535a + BoardNames[0]: 'bus=ahb,bmi-chip-id=0,bmi-board-id=16,variant=GO_GALE' + BoardLength[0]: 12064 + BoardCRC32[0]: e117f336 + BoardMD5[0]: ea35e78c88a8571201da8b75edc9b881 + BoardNames[1]: 'bus=ahb,bmi-chip-id=0,bmi-board-id=21,variant=GO_GALE' + BoardLength[1]: 12064 + BoardCRC32[1]: 6c751ec9 + BoardMD5[1]: 44cbc4ca6cb7141ba4249615f7065582 + BoardNames[2]: 'bus=ahb,bmi-chip-id=0,bmi-board-id=16,variant=GO_BREEZE' + BoardLength[2]: 12064 + BoardCRC32[2]: 24fba117 + BoardMD5[2]: b4ac055b3ab67d5a6f5607a96af39a1f + BoardNames[3]: 'bus=ahb,bmi-chip-id=0,bmi-board-id=21,variant=GO_BREEZE' + BoardLength[3]: 12064 + BoardCRC32[3]: a3e16b2a + BoardMD5[3]: 8b26cb285032314247304114b8ac50e7 + +Naming follows existing Google projects included in upstream board-2.bin +-- GO(ogle) prefix, an underscore (_), and the project code name, all in +caps. + +Note that I only tested the "gale" model; the "breeze" model is a later +revision (same marketing name) with very small hardware changes but +otherwise using the same firmware image. + +Submitted upstream here: + + ath10k-firmware: QCA4019: hw1.0: Add Google Wifi BDFs + http://lists.infradead.org/pipermail/ath10k/2022-March/013465.html + https://lore.kernel.org/ath10k/YjaNGW252Ls%2FyDw8@localhost/ + +Signed-off-by: Brian Norris +(cherry picked from commit 331d78a90f3f11e9abfbc114a601c565899e3764) +Signed-off-by: Jan-Niklas Burfeind + +diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile +index be9b547cd052579880dbac38c64a940617ddd932..74d789bdf66c6fda407e060a1c91b0e0965c147c 100644 +--- a/package/firmware/ipq-wifi/Makefile ++++ b/package/firmware/ipq-wifi/Makefile +@@ -43,6 +43,7 @@ ALLWIFIBOARDS:= \ + glinet_gl-ap1300 \ + glinet_gl-b2200 \ + glinet_gl-s1300 \ ++ google_wifi \ + linksys_ea8300 \ + linksys_mr8300-v0 \ + luma_wrtq-329acn \ +@@ -134,6 +135,7 @@ $(eval $(call generate-ipq-wifi-package,ezviz_cs-w3-wd1200g-eup,EZVIZ CS-W3-WD12 + $(eval $(call generate-ipq-wifi-package,glinet_gl-ap1300,GL.iNet GL-AP1300)) + $(eval $(call generate-ipq-wifi-package,glinet_gl-b2200,GL.iNet GL-B2200)) + $(eval $(call generate-ipq-wifi-package,glinet_gl-s1300,GL.iNet GL-S1300)) ++$(eval $(call generate-ipq-wifi-package,google_wifi,Google WiFi)) + $(eval $(call generate-ipq-wifi-package,linksys_ea8300,Linksys EA8300)) + $(eval $(call generate-ipq-wifi-package,linksys_mr8300-v0,Linksys MR8300)) + $(eval $(call generate-ipq-wifi-package,luma_wrtq-329acn,Luma WRTQ-329ACN)) +diff --git a/package/firmware/ipq-wifi/board-google_wifi.qca4019 b/package/firmware/ipq-wifi/board-google_wifi.qca4019 +new file mode 100644 +index 0000000000000000000000000000000000000000..1c10731f0d4945c9751ed797a679619ac621b6ac +GIT binary patch +literal 48596 +zcmeHQdsI_L8lNC9pKwD&dGr#J011Qu@f9@|M5G`oTGv;oONCMku~YOD)IMR>k^gZBO-d|LUHzd+eU>cJ~~6*6sGaXS=d9_vR)y$-R;U&=}@} +znfd0M*Ehd=6K*n}Kc8B(FnQsMoV3)uY +zNoUeHk>d#0>S7@H(6Q%UdL=Lj1-4mgmR{YCy_tFlqrkn;Ka2tS$mq5*ozvs9XhpYV +zg0;68&_7m#MG*nKHA5-i-3i4&(xacclaXNlF;V$pi7mItX+ +zG@nAZjYaHNzJ20!QGsCDl7hV4xtDs{cQ;j*J(WBAQZLl1%9iKO`Wedg +zj}!^uZqMnRO&iLdEXcUs+rF!=v_O}uy>t?FE6B~&zyYr})k52RYQT+zL~ytJbVJ>m +zf_b@0ICMwdvjthO+p+d0I5bZqzjV5NUtLAPa!smbK!Ux0L)7Y^4AI5D84s|>gS+Mn +zC~@!X(Xw9a*syhpA$4_l`l%yTjdM!kRz~Js?Ag?oy<1*6eO+7c(`|Eii>tzl&L1vo +z$lD-&GCbpa*T!A*OBMPk-G?XZ4ldoTs(S3%_j+sFo_syIHhTTFBNYwV&q;E_=3VXH +zxMRu2_?6*V$B&h@<}@YMMwOmFU2`;LTTDgRx@9;pK+yP!lS7EGsna5&9*be# +z@ogn~kF^Oi%C3YDMDX!K;OFNjK>4_F0RaJl776NW-Cnxv#w*L@BAHAIf8!*vu~JE_ +zM6$|1*x{MPZcCw%o@Mm%ic|1;1WsSEt@#v6XeA{}66NtSNh~rX%AsP>hG~;<%;$lP +z3l)MSh=t@rB8^NVDyp|^+wofS{w_v2WmSM&MTz;iRf(ddz1^xrTI7&b5t2fc@KYfX +zNk*z7b)jS^F`djLGgXrT$b+%p>Qi=IK(&R6;{CYqy%L +z{@ANPn!-rekgC{vjk>tiSbBpn?_#N}zOjsSb~0M5$Eui-jt)i>+o=&&X|rk(JgUel +zEmlp$R)?G+j10RQMnsWOswmwea?#yIL>`%^%G1ptXWX4Z%qQoo=If|?qm|0(3(^%M +zl}g|4WanZTln!=|prTRY=TzKtyTG$aSvIl6Z%UNfCyr?_E??Jo}}xw#FE~gm~+|f`EP00{^aD?Z-cZSGMTZmKytS +z0szaGj2-w62#_%o0Hcr)ghSbDDO)V1JeUAlp!LrH1o-5tVmkn7KuQ20hJiN{ +z7|+8bEwpC_C_c*!Qv3lXR8lF_p8!GI1H>m_`|Z!}fX_d_LzPHJ35)L{FxWRq9{*U>}g!nkw!%Xza9eq|upU&x)tyr^mT}i2N +zZ%gapj_wnu`ufjZ{NVb>H{EXl9zC``N`nA(4yqG2GAE(b8K^F^kvRpW&OdePM&<<6 +zeGqv^_&&Oi(w*Q#zPfT|oWH7Yee;1M$INF3KH}4T2ok%ki0+AqXfj$AtrLN)ds&2z +z)Twm3EHLxlOhQX)Ra)K55&L{?x3J5VaCJCA3bWPOM80sgdN%R6u;38-ah`zrJI9od +z%10bGu|{ewUNgY941OGSTA?Erx&-hOHjjS7rZnu6l(`9z_Y(6G_*_5u`d +ze|cPpmPww*+r#zVbzIXf-d^BpY+DF;ReTj({dAI3ygl*}twF-)Wt*gnf`Wnqf&#|{ +z_>W@*fc`-`48Pyy_;(lL?QM%fjXU1nuFFsr7$*ZzVg!C(04OoyW_>agW~is7E#BU7 +zh73`M=rhsfsp9Zu;oHOeY+gEcsgs0iTY#$5b(C9{WOdjLnO}lc3cp*xzxQ+W@ +z1TX@=ihuyL44$(*v-pDrgDWliHGcpIi~jxKYlE#8Jr?|UFT$e#3HAxL=sN~&^VG8X +zKYZNQtXZB<$JYP!)3^U($JWO{=l*-=Z-4pXi$6lm7H>cJ&wqUR_19lPTL^rJw2lAn +zySrc0|k7DOs@%AYxDiunqWE5o& +zW9!M0(UeJv)O2EUWHk0Z7@aHLzSSD)ZdI(`+FW2hjJc$YZoEC?idJiN2CEDxZb9P8 +zcPI3{z|N_q=ygUtNB1i`)*k7@47ZQdtwCRMU%YAm3By)nUL$y^@V!Pz**CQ`c3+5P29j4bGNbHpw~pBeSm~4Rln-id*;K&YQwMebIk7<4;U(Q +zvNUQqV1NA!%z#T*5)|Op1@jSO4V-t@K%e<-V}n7j*O~{6?S{=ci{;a)6*d^2rd=Ai +z0$sXw-rR0_*;sB^Jn)XW%hUu1=bPU*wi#-2a^z71=S*)=F2x|1E?<=^0Nm)Um&snHRx%Ixe%UEYvt%;-uDB{r`_L;UA*VpI6#v{g;49oN> +z(2=(KYJHwYaqF!4kg?LRG)IO8d~ihpQF?cv%~WM9tk1f24mMWRuQe=zZgxT}Gc+V@ +zJ#4BqEXs+X23&`Ga7VoGQ6IbH$_2zIVU&0f@P%80XKUCzW)WyT^WyRJmgL5$nojet +z+q3p0G(^0(`9Ss##iq#ON!gdXpL=6Lz4ZBM`pz?(k7w>rX^g5q)3@HV3C$3y+!0j%MurSV`Yc5yQEcNYu{*Iy>+HR^0YAH +zOi$I}{5Rya)1Mo&HxAx7M!*LUuw&n_eJHbP=<)x40?z_%!huI$<2p^~jjhYnWL%sK +z{zB#ru{1VT61xg`4f}?3EIbo#A3S1b_0DTB;r8Q4Yz+?hN5yndh<^SZ95Vh+@PBss +z0VbUl{u1&_$e+g-2R;{wY_qn~=`1`s-#z6jWPhx$#t7<`tR{|uZ5rJsf03WZ@`P00=shOqmO$|ik$((jzaVZ*KldyI5H +z2RFuAb*OmzWGG3AiiG%hT1$wN$%buHSZASlc&Pb2v_Zm^B+9=yT7xr7hig;F;Vg*x +zCP^WOJVA(^1!|tzlAt6iQ=f2JR@Aoti58uz@VH8a_ +zr0SGSf(f!tX2AIP3EhhARJvv>*98*5&(D9tT3CjL0znpx!%v(m+Z5`b2IJ}{i0zZV +z*!%ZCc0EM#@c#ZKU`^|Z>!T45KibIh#o06VhZ$>+)*jt>`-Id~6?K-x%HUC|GL^R> +z9=5VNQz|qmm5)JjY@q7yH$c*`D9)+eZ+NKj_VU!!G{=3Ykvxb7-V5b^gZo#|J4YZg +zI>+ll)gMFyqA=rJ-2Dbu&W!nD?AdmS^_8qv^Xc){K1wB@9vyAl*l=|A)#1}4B5Z5% +z>7K>gi_yf1bS^`>lAY7`Xk^#kKd0Zi=$v+zozwQQ6K_8U{sDKJ-#&Bs;>87vS^V~G +z7X+B!p7kii9rup;?O71Hq1xi@TP&k6zdh!+ce;Um;jr5a_uz!{BWS?<_K)C2dx$RE +zov_7N57w-T{plK~qws+UG7w;Xdrok?&B(=1kNNG<*G3N9_#SZC)3d(3Q$ +zZ{?Hsa(;VpyoHlKu4_m&2A#4Xk#%ybv2n~~oh(%>qem%a9f)g)5|2sknF%1_J2$C4 +z%Q_?_J*xvZsXfce>dURV^4$p!zx@%4-`pFkqB8Kyfl*l$;>pF!%yW9NWSsi~vReBY+XW2w()pBm&N{@HpOnOx_51 +z(+?kkF&@7^RJ^@6aoKbE;!RxkT)v?1LNUL+=Pz^2Z|^yFc;x*N!2I^;f2PL#_Eey& +z``JT{w|C!NJOU#yGy<-i8MEW+`ShVzdNg}@7H|I`_lo1~QVc+kbKg^V_qZlQ6$Mg9hfeXOOU!zHlmw_h7r8{F*PI#J@Y-f)T(7_&x%d-yZYZ +zV}ASQ{jDZz{J*_w<=n@l_ROdB3yk6>B(8jS!e+Lob!sts$x+YI`#t8j$Nct~-yQ&8 +z_`CS*c5yA4daE|H6{PvjNp5q1cfJ{#G_TM=yJkoLRuFmJ+##pNk6>mRmE_*I+d=I(o +zxp?p)aSG +Date: Sat, 4 Feb 2023 16:35:35 -0800 +Subject: ipq40xx: chromium: Enable kmod-ramoops by default + +Chromium devices (like Google WiFi) have ramoops memory reserved by the +bootloader. Let's enable the ramoops kernel module by default, so we get +better crash logging. + +Signed-off-by: Brian Norris +Signed-off-by: Jan-Niklas Burfeind +(updated makefile after missing drop commit) + +diff --git a/target/linux/ipq40xx/image/chromium.mk b/target/linux/ipq40xx/image/chromium.mk +index 2c8457dcfbbb042e6bda08ae946e1219af4c4ffc..e17398929e939ee3590ea34bd76b41aa089b4f89 100644 +--- a/target/linux/ipq40xx/image/chromium.mk ++++ b/target/linux/ipq40xx/image/chromium.mk +@@ -30,7 +30,11 @@ define Device/google_wifi + KERNEL_NAME := zImage + IMAGES += factory.bin + IMAGE/factory.bin := cros-gpt | append-kernel-part | append-rootfs ++ # Note: Chromium/Depthcharge-based bootloaders insert a reserved-memory ++ # ramoops node into the Device Tree automatically, so we can use ++ # kmod-ramoops. + DEVICE_PACKAGES := ipq-wifi-google_wifi partx-utils mkf2fs e2fsprogs \ +- kmod-fs-ext4 kmod-fs-f2fs kmod-google-firmware ++ kmod-fs-ext4 kmod-fs-f2fs kmod-google-firmware \ ++ kmod-ramoops + endef + TARGET_DEVICES += google_wifi diff --git a/patches/openwrt/0015-ipq40xx-qcom_scm-Disable-SDI-at-boot.patch b/patches/openwrt/0015-ipq40xx-qcom_scm-Disable-SDI-at-boot.patch new file mode 100644 index 00000000..c74fb990 --- /dev/null +++ b/patches/openwrt/0015-ipq40xx-qcom_scm-Disable-SDI-at-boot.patch @@ -0,0 +1,69 @@ +From: Brian Norris +Date: Tue, 21 Jul 2020 00:23:07 -0700 +Subject: ipq40xx: qcom_scm: Disable SDI at boot + +See my upstream RFC of this: +https://lore.kernel.org/linux-arm-msm/20200721080054.2803881-1-computersforpeace@gmail.com/ + +This fixes warm boot (reboot) for Google WiFi devices using their +factory bootloader/firmware. + +I may resend this upstream eventually. + +Signed-off-by: Brian Norris +(cherry picked from commit a93ec36630ef4ff5a2195ad613b616bffa50d00d) +Signed-off-by: Jan-Niklas Burfeind + +diff --git a/target/linux/ipq40xx/patches-5.10/420-firmware-qcom-scm-disable-SDI.patch b/target/linux/ipq40xx/patches-5.10/420-firmware-qcom-scm-disable-SDI.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..eb474500b1b100423cf96e494f2f52d50ee0aaba +--- /dev/null ++++ b/target/linux/ipq40xx/patches-5.10/420-firmware-qcom-scm-disable-SDI.patch +@@ -0,0 +1,47 @@ ++--- a/drivers/firmware/qcom_scm.c +++++ b/drivers/firmware/qcom_scm.c ++@@ -404,6 +404,20 @@ static int __qcom_scm_set_dload_mode(str ++ return qcom_scm_call_atomic(__scm->dev, &desc, NULL); ++ } ++ +++static int __qcom_scm_disable_sdi(struct device *dev) +++{ +++ struct qcom_scm_desc desc = { +++ .svc = QCOM_SCM_SVC_BOOT, +++ .cmd = QCOM_SCM_BOOT_CONFIG_SDI, +++ .arginfo = QCOM_SCM_ARGS(2), +++ .args[0] = 1 /* 1: disable watchdog debug */, +++ .args[1] = 0 /* 0: disable SDI */, +++ .owner = ARM_SMCCC_OWNER_SIP, +++ }; +++ +++ return qcom_scm_call(__scm->dev, &desc, NULL); +++} +++ ++ static void qcom_scm_set_download_mode(bool enable) ++ { ++ bool avail; ++@@ -1256,6 +1270,13 @@ static int qcom_scm_probe(struct platfor ++ if (download_mode) ++ qcom_scm_set_download_mode(true); ++ +++ /* +++ * Factory firmware leaves SDI (a debug interface), which prevents +++ * clean reboot. +++ */ +++ if (of_machine_is_compatible("google,wifi")) +++ __qcom_scm_disable_sdi(__scm->dev); +++ ++ return 0; ++ } ++ ++--- a/drivers/firmware/qcom_scm.h +++++ b/drivers/firmware/qcom_scm.h ++@@ -77,6 +77,7 @@ extern int scm_legacy_call(struct device ++ #define QCOM_SCM_SVC_BOOT 0x01 ++ #define QCOM_SCM_BOOT_SET_ADDR 0x01 ++ #define QCOM_SCM_BOOT_TERMINATE_PC 0x02 +++#define QCOM_SCM_BOOT_CONFIG_SDI 0x09 ++ #define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10 ++ #define QCOM_SCM_BOOT_SET_REMOTE_STATE 0x0a ++ #define QCOM_SCM_FLUSH_FLAG_MASK 0x3 diff --git a/patches/openwrt/0016-ipq40xx-google-gale-add-reset-button.patch b/patches/openwrt/0016-ipq40xx-google-gale-add-reset-button.patch new file mode 100644 index 00000000..2af2f92b --- /dev/null +++ b/patches/openwrt/0016-ipq40xx-google-gale-add-reset-button.patch @@ -0,0 +1,30 @@ +From: Jan-Niklas Burfeind +Date: Sat, 25 Mar 2023 19:55:41 +0100 +Subject: ipq40xx: google (gale) add reset button + +add the external button (GPIO 57) as reset button + +Signed-off-by: Jan-Niklas Burfeind +(cherry picked from commit 5c41ab35562fdb814e943ea5eae513e9fa75c81d) + +diff --git a/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-wifi.dts b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-wifi.dts +index 9448e5145e29c39d4f7bfc2b94a745b2ccc1cf2d..1c294689ea72edf2f238e00d5e7fa0a5239c360a 100644 +--- a/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-wifi.dts ++++ b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-wifi.dts +@@ -39,6 +39,16 @@ + status = "okay"; + }; + }; ++ ++ keys { ++ compatible = "gpio-keys"; ++ ++ reset { ++ label = "reset"; ++ gpios = <&tlmm 57 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ }; ++ }; + }; + + &tlmm { diff --git a/targets/ipq40xx-chromium b/targets/ipq40xx-chromium new file mode 100644 index 00000000..a880ec63 --- /dev/null +++ b/targets/ipq40xx-chromium @@ -0,0 +1,5 @@ +-- Google + +device('google-wifi-gale', 'google_wifi', { + broken = true, -- can only be flashed by opening the device, to enter devmode +}) diff --git a/targets/targets.mk b/targets/targets.mk index 346377ea..fb1479d7 100644 --- a/targets/targets.mk +++ b/targets/targets.mk @@ -3,6 +3,7 @@ $(eval $(call GluonTarget,ath79,nand)) $(eval $(call GluonTarget,ath79,mikrotik)) $(eval $(call GluonTarget,bcm27xx,bcm2708)) $(eval $(call GluonTarget,bcm27xx,bcm2709)) +$(eval $(call GluonTarget,ipq40xx,chromium)) $(eval $(call GluonTarget,ipq40xx,generic)) $(eval $(call GluonTarget,ipq40xx,mikrotik)) $(eval $(call GluonTarget,ipq806x,generic))