From 378c7ff282101b204d2a29fa080ed66f2a14940d Mon Sep 17 00:00:00 2001 From: Alexander Couzens Date: Sun, 17 Jan 2021 06:54:04 +0100 Subject: [PATCH 01/34] ipq40xx: split generic images into own file In preparation of the new mikrotik subtarget split the generic images into generic.mk Signed-off-by: Alexander Couzens --- target/linux/ipq40xx/image/Makefile | 807 +------------------------ target/linux/ipq40xx/image/generic.mk | 809 ++++++++++++++++++++++++++ 2 files changed, 810 insertions(+), 806 deletions(-) create mode 100644 target/linux/ipq40xx/image/generic.mk diff --git a/target/linux/ipq40xx/image/Makefile b/target/linux/ipq40xx/image/Makefile index f10ff002dc..a764cb60af 100644 --- a/target/linux/ipq40xx/image/Makefile +++ b/target/linux/ipq40xx/image/Makefile @@ -1,10 +1,6 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/image.mk -DEVICE_VARS += NETGEAR_BOARD_ID NETGEAR_HW_ID -DEVICE_VARS += RAS_BOARD RAS_ROOTFS_SIZE RAS_VERSION -DEVICE_VARS += WRGG_DEVNAME WRGG_SIGNATURE - define Device/Default PROFILES := Default KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts) @@ -18,807 +14,6 @@ define Device/Default IMAGE/sysupgrade.bin/squashfs := endef -define Device/FitImage - KERNEL_SUFFIX := -fit-uImage.itb - KERNEL = kernel-bin | gzip | fit gzip $$(DTS_DIR)/$$(DEVICE_DTS).dtb - KERNEL_NAME := Image -endef - -define Device/FitImageLzma - KERNEL_SUFFIX := -fit-uImage.itb - KERNEL = kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb - KERNEL_NAME := Image -endef - -define Device/FitzImage - KERNEL_SUFFIX := -fit-zImage.itb - KERNEL = kernel-bin | fit none $$(DTS_DIR)/$$(DEVICE_DTS).dtb - KERNEL_NAME := zImage -endef - -define Device/UbiFit - KERNEL_IN_UBI := 1 - IMAGES := nand-factory.ubi nand-sysupgrade.bin - IMAGE/nand-factory.ubi := append-ubi - IMAGE/nand-sysupgrade.bin := sysupgrade-tar | append-metadata -endef - -define Device/DniImage - $(call Device/FitzImage) - NETGEAR_BOARD_ID := - NETGEAR_HW_ID := - IMAGES += factory.img - IMAGE/factory.img := append-kernel | pad-offset 64k 64 | append-uImage-fakehdr filesystem | append-rootfs | pad-rootfs | netgear-dni - IMAGE/sysupgrade.bin := append-kernel | pad-offset 64k 64 | append-uImage-fakehdr filesystem | \ - append-rootfs | pad-rootfs | append-metadata | check-size -endef - -define Build/append-rootfshdr - mkimage -A $(LINUX_KARCH) \ - -O linux -T filesystem \ - -C lzma -a $(KERNEL_LOADADDR) -e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \ - -n root.squashfs -d $(IMAGE_ROOTFS) $@.new - dd if=$@.new bs=64 count=1 >> $(IMAGE_KERNEL) -endef - -define Build/mkmylofw_32m - $(eval device_id=$(word 1,$(1))) - $(eval revision=$(word 2,$(1))) - - let \ - size="$$(stat -c%s $@)" \ - pad="$(subst k,* 1024,$(BLOCKSIZE))" \ - pad="(pad - (size % pad)) % pad" \ - newsize='size + pad'; \ - $(STAGING_DIR_HOST)/bin/mkmylofw \ - -B WPE72 -i 0x11f6:$(device_id):0x11f6:$(device_id) -r $(revision) \ - -s 0x2000000 -p0x180000:$$newsize:al:0x80208000:"OpenWrt":$@ \ - $@.new - @mv $@.new $@ -endef - -define Build/qsdk-ipq-factory-nand-askey - $(TOPDIR)/scripts/mkits-qsdk-ipq-image.sh $@.its\ - askey_kernel $(IMAGE_KERNEL) \ - askey_fs $(IMAGE_ROOTFS) \ - ubifs $@ - PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage -f $@.its $@.new - @mv $@.new $@ -endef - -define Build/SenaoFW - -$(STAGING_DIR_HOST)/bin/mksenaofw \ - -n $(BOARD_NAME) -r $(VENDOR_ID) -p $(1) \ - -c $(DATECODE) -w $(2) -x $(CW_VER) -t 0 \ - -e $@ \ - -o $@.new - @cp $@.new $@ -endef - -define Build/wrgg-image - mkwrggimg -i $@ \ - -o $@.new \ - -d "$(WRGG_DEVNAME)" \ - -s "$(WRGG_SIGNATURE)" \ - -v "" -m "" -B "" - mv $@.new $@ -endef - -define Device/8dev_habanero-dvk - $(call Device/FitImageLzma) - DEVICE_VENDOR := 8devices - DEVICE_MODEL := Habanero DVK - IMAGE_SIZE := 30976k - SOC := qcom-ipq4019 - DEVICE_PACKAGES := ipq-wifi-8dev_habanero-dvk - IMAGE/sysupgrade.bin := append-kernel | pad-to 64k | append-rootfs | pad-rootfs | append-metadata | check-size -endef -TARGET_DEVICES += 8dev_habanero-dvk - -define Device/8dev_jalapeno-common - $(call Device/FitImage) - $(call Device/UbiFit) - BLOCKSIZE := 128k - PAGESIZE := 2048 - SOC := qcom-ipq4018 -endef - -define Device/8dev_jalapeno - $(call Device/8dev_jalapeno-common) - DEVICE_VENDOR := 8devices - DEVICE_MODEL := Jalapeno -endef -TARGET_DEVICES += 8dev_jalapeno - -define Device/alfa-network_ap120c-ac - $(call Device/FitImage) - $(call Device/UbiFit) - DEVICE_VENDOR := ALFA Network - DEVICE_MODEL := AP120C-AC - SOC := qcom-ipq4018 - DEVICE_PACKAGES := kmod-usb-acm \ - kmod-tpm-i2c-atmel uboot-envtools - BLOCKSIZE := 128k - PAGESIZE := 2048 - IMAGE_SIZE := 65536k - IMAGES := nand-factory.bin nand-sysupgrade.bin - IMAGE/nand-factory.bin := append-ubi | qsdk-ipq-factory-nand -endef -TARGET_DEVICES += alfa-network_ap120c-ac - -define Device/aruba_glenmorangie - $(call Device/FitImageLzma) - DEVICE_VENDOR := Aruba - SOC := qcom-ipq4029 - DEVICE_PACKAGES := ipq-wifi-aruba_ap-303 -endef - -define Device/aruba_ap-303 - $(call Device/aruba_glenmorangie) - DEVICE_MODEL := AP-303 - DEVICE_PACKAGES += uboot-envtools -endef -TARGET_DEVICES += aruba_ap-303 - -define Device/aruba_ap-303h - $(call Device/aruba_glenmorangie) - DEVICE_MODEL := AP-303H -endef -TARGET_DEVICES += aruba_ap-303h - -define Device/aruba_ap-365 - $(call Device/aruba_glenmorangie) - DEVICE_MODEL := AP-365 - DEVICE_PACKAGES += kmod-hwmon-ad7418 uboot-envtools -endef -TARGET_DEVICES += aruba_ap-365 - -define Device/asus_map-ac2200 - $(call Device/FitImageLzma) - DEVICE_VENDOR := ASUS - DEVICE_MODEL := Lyra (MAP-AC2200) - SOC := qcom-ipq4019 - DEVICE_PACKAGES := ath10k-firmware-qca9888-ct kmod-ath3k -endef -TARGET_DEVICES += asus_map-ac2200 - -define Device/asus_rt-ac58u - $(call Device/FitImageLzma) - DEVICE_VENDOR := ASUS - DEVICE_MODEL := RT-AC58U - SOC := qcom-ipq4018 - BLOCKSIZE := 128k - PAGESIZE := 2048 - DTB_SIZE := 65536 - IMAGE_SIZE := 20439364 - FILESYSTEMS := squashfs -# Someone - in their infinite wisdom - decided to put the firmware -# version in front of the image name \03\00\00\04 => Version 3.0.0.4 -# Since u-boot works with strings we either need another fixup step -# to add a version... or we are very careful not to add '\0' into that -# string and call it a day.... Yeah, we do the latter! - UIMAGE_NAME:=$(shell echo -e '\03\01\01\01RT-AC58U') - DEVICE_PACKAGES := -kmod-ath10k-ct kmod-ath10k-ct-smallbuffers \ - kmod-usb-ledtrig-usbport -endef -TARGET_DEVICES += asus_rt-ac58u - -define Device/avm_fritzbox-4040 - $(call Device/FitImageLzma) - DEVICE_VENDOR := AVM - DEVICE_MODEL := FRITZ!Box 4040 - SOC := qcom-ipq4018 - BOARD_NAME := fritz4040 - IMAGE_SIZE := 29056k - UBOOT_PATH := $(STAGING_DIR_IMAGE)/uboot-fritz4040.bin - UBOOT_PARTITION_SIZE := 524288 - IMAGES += eva.bin - IMAGE/eva.bin := append-uboot | pad-to $$$$(UBOOT_PARTITION_SIZE) | append-kernel | append-rootfs | pad-rootfs - IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata | check-size - DEVICE_PACKAGES := fritz-tffs fritz-caldata -endef -TARGET_DEVICES += avm_fritzbox-4040 - -define Device/avm_fritzbox-7530 - $(call Device/FitImageLzma) - DEVICE_VENDOR := AVM - DEVICE_MODEL := FRITZ!Box 7530 - SOC := qcom-ipq4019 - DEVICE_PACKAGES := fritz-caldata fritz-tffs-nand -endef -TARGET_DEVICES += avm_fritzbox-7530 - -define Device/avm_fritzrepeater-1200 - $(call Device/FitImageLzma) - DEVICE_VENDOR := AVM - DEVICE_MODEL := FRITZ!Repeater 1200 - SOC := qcom-ipq4019 - DEVICE_PACKAGES := fritz-caldata fritz-tffs-nand ipq-wifi-avm_fritzrepeater-1200 -endef -TARGET_DEVICES += avm_fritzrepeater-1200 - -define Device/avm_fritzrepeater-3000 - $(call Device/FitImageLzma) - DEVICE_VENDOR := AVM - DEVICE_MODEL := FRITZ!Repeater 3000 - SOC := qcom-ipq4019 - DEVICE_PACKAGES := ath10k-firmware-qca9984-ct fritz-caldata fritz-tffs-nand -endef -TARGET_DEVICES += avm_fritzrepeater-3000 - -define Device/buffalo_wtr-m2133hp - $(call Device/FitImage) - $(call Device/UbiFit) - DEVICE_VENDOR := Buffalo - DEVICE_MODEL := WTR-M2133HP - SOC := qcom-ipq4019 - DEVICE_PACKAGES := uboot-envtools ath10k-firmware-qca9984-ct ipq-wifi-buffalo_wtr-m2133hp - BLOCKSIZE := 128k - PAGESIZE := 2048 -endef -TARGET_DEVICES += buffalo_wtr-m2133hp - -define Device/cellc_rtl30vw - KERNEL_SUFFIX := -fit-uImage.itb - KERNEL_INITRAMFS = kernel-bin | gzip | fit gzip $$(DTS_DIR)/$$(DEVICE_DTS).dtb - KERNEL = kernel-bin | gzip | fit gzip $$(DTS_DIR)/$$(DEVICE_DTS).dtb | uImage lzma | pad-to 2048 - KERNEL_NAME := Image - KERNEL_IN_UBI := - IMAGES := nand-factory.bin nand-sysupgrade.bin - IMAGE/nand-factory.bin := append-rootfshdr | append-ubi | qsdk-ipq-factory-nand-askey - IMAGE/nand-sysupgrade.bin := append-rootfshdr | sysupgrade-tar | append-metadata - DEVICE_VENDOR := Cell C - DEVICE_MODEL := RTL30VW - SOC := qcom-ipq4019 - DEVICE_DTS_CONFIG := config@5 - KERNEL_INSTALL := 1 - KERNEL_SIZE := 4096k - IMAGE_SIZE := 57344k - BLOCKSIZE := 128k - PAGESIZE := 2048 - DEVICE_PACKAGES := kmod-usb-net-qmi-wwan kmod-usb-serial-option uqmi ipq-wifi-cellc_rtl30vw -endef -TARGET_DEVICES += cellc_rtl30vw - -define Device/cilab_meshpoint-one - $(call Device/8dev_jalapeno-common) - DEVICE_VENDOR := Crisis Innovation Lab - DEVICE_MODEL := MeshPoint.One - DEVICE_PACKAGES := kmod-i2c-gpio kmod-iio-bmp280-i2c kmod-hwmon-ina2xx kmod-rtc-pcf2127 -endef -TARGET_DEVICES += cilab_meshpoint-one - -define Device/compex_wpj419 - $(call Device/FitImage) - $(call Device/UbiFit) - DEVICE_VENDOR := Compex - DEVICE_MODEL := WPJ419 - SOC := qcom-ipq4019 - DEVICE_DTS_CONFIG := config@12 - KERNEL_INSTALL := 1 - BLOCKSIZE := 128k - PAGESIZE := 2048 - FILESYSTEMS := squashfs -endef -TARGET_DEVICES += compex_wpj419 - -define Device/compex_wpj428 - $(call Device/FitImage) - DEVICE_VENDOR := Compex - DEVICE_MODEL := WPJ428 - SOC := qcom-ipq4028 - DEVICE_DTS_CONFIG := config@4 - BLOCKSIZE := 64k - IMAGE_SIZE := 31232k - KERNEL_SIZE := 4096k - IMAGES += cpximg-6a04.bin - IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata - IMAGE/cpximg-6a04.bin := append-kernel | append-rootfs | pad-rootfs | mkmylofw_32m 0x8A2 3 - DEVICE_PACKAGES := kmod-gpio-beeper -endef -TARGET_DEVICES += compex_wpj428 - -define Device/devolo_magic-2-wifi-next - $(call Device/FitImage) - DEVICE_VENDOR := devolo - DEVICE_MODEL := Magic 2 WiFi next - SOC := qcom-ipq4018 - KERNEL_SIZE := 4096k - - # If the bootloader sees 0xDEADC0DE and this trailer at the 64k boundary of a TFTP image - # it will bootm it, just like we want for the initramfs. - KERNEL_INITRAMFS := kernel-bin | gzip | fit gzip $$(DTS_DIR)/$$(DEVICE_DTS).dtb | pad-to 64k |\ - append-string -e '\xDE\xAD\xC0\xDE{"fl_initramfs":""}\x00' - - IMAGE_SIZE := 26624k - IMAGES := sysupgrade.bin - IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata - DEVICE_PACKAGES := ipq-wifi-devolo_magic-2-wifi-next uboot-envtools -endef -TARGET_DEVICES += devolo_magic-2-wifi-next - -define Device/dlink_dap-2610 - $(call Device/FitImageLzma) - DEVICE_VENDOR := D-Link - DEVICE_MODEL := DAP-2610 - SOC := qcom-ipq4018 - DEVICE_DTS_CONFIG := config@ap.dk01.1-c1 - BLOCKSIZE := 64k - WRGG_DEVNAME := /dev/mtdblock/8 - WRGG_SIGNATURE := wapac30_dkbs_dap2610 - IMAGE_SIZE := 14080k - IMAGES += factory.bin - # Bootloader expects a special 160 byte header which is added by - # wrgg-image. - # Factory image size must be larger than 6MB, and size in wrgg header must - # match actual factory image size to be flashable from D-Link http server. - # Bootloader verifies checksum of wrgg image before booting, thus jffs2 - # cannot be part of the wrgg image. This is solved in the factory image by - # having the rootfs at the end of the image (without pad-rootfs). And in - # the sysupgrade image only the kernel is included in the wrgg checksum, - # but this is not flashable from the D-link http server. - # append-rootfs must start on an erase block boundary. - IMAGE/factory.bin := append-kernel | pad-offset 6144k 160 | append-rootfs | wrgg-image | check-size - IMAGE/sysupgrade.bin := append-kernel | wrgg-image | pad-to $$$$(BLOCKSIZE) | append-rootfs | pad-rootfs | check-size | append-metadata - DEVICE_PACKAGES := ipq-wifi-dlink_dap2610 -endef -TARGET_DEVICES += dlink_dap-2610 - -define Device/edgecore_ecw5211 - $(call Device/FitImage) - $(call Device/UbiFit) - DEVICE_VENDOR := Edgecore - DEVICE_MODEL := ECW5211 - SOC := qcom-ipq4018 - BLOCKSIZE := 128k - PAGESIZE := 2048 - DEVICE_PACKAGES := kmod-tpm-i2c-atmel kmod-usb-acm uboot-envtools -endef -TARGET_DEVICES += edgecore_ecw5211 - -define Device/edgecore_oap100 - $(call Device/FitImage) - $(call Device/UbiFit) - DEVICE_VENDOR := Edgecore - DEVICE_MODEL := OAP100 - SOC := qcom-ipq4019 - BLOCKSIZE := 128k - PAGESIZE := 2048 - IMAGES := nand-sysupgrade.bin - DEVICE_DTS_CONFIG := config@ap.dk07.1-c1 - DEVICE_PACKAGES := ipq-wifi-edgecore_oap100 kmod-usb-acm kmod-usb-net kmod-usb-net-cdc-qmi uqmi -endef -TARGET_DEVICES += edgecore_oap100 - -define Device/engenius_eap1300 - $(call Device/FitImage) - DEVICE_VENDOR := EnGenius - DEVICE_MODEL := EAP1300 - DEVICE_DTS_CONFIG := config@4 - BOARD_NAME := eap1300 - SOC := qcom-ipq4018 - KERNEL_SIZE := 5120k - IMAGE_SIZE := 25344k - IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata -endef -TARGET_DEVICES += engenius_eap1300 - -define Device/engenius_eap2200 - $(call Device/FitImage) - $(call Device/UbiFit) - DEVICE_VENDOR := EnGenius - DEVICE_MODEL := EAP2200 - SOC := qcom-ipq4019 - BLOCKSIZE := 128k - PAGESIZE := 2048 - DEVICE_PACKAGES := ath10k-firmware-qca9888-ct ipq-wifi-engenius_eap2200 -kmod-ath10k-ct kmod-ath10k-ct-smallbuffers -endef -TARGET_DEVICES += engenius_eap2200 - -define Device/engenius_emd1 - $(call Device/FitImage) - DEVICE_VENDOR := EnGenius - DEVICE_MODEL := EMD1 - DEVICE_DTS_CONFIG := config@4 - SOC := qcom-ipq4018 - IMAGE_SIZE := 30720k - IMAGES += factory.bin - IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata - IMAGE/factory.bin := qsdk-ipq-factory-nor | check-size -endef -TARGET_DEVICES += engenius_emd1 - -define Device/engenius_emr3500 - $(call Device/FitImage) - DEVICE_VENDOR := EnGenius - DEVICE_MODEL := EMR3500 - DEVICE_DTS_CONFIG := config@4 - SOC := qcom-ipq4018 - KERNEL_SIZE := 4096k - IMAGE_SIZE := 30720k - IMAGES += factory.bin - IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata - IMAGE/factory.bin := qsdk-ipq-factory-nor | check-size -endef -TARGET_DEVICES += engenius_emr3500 - -define Device/engenius_ens620ext - $(call Device/FitImage) - DEVICE_VENDOR := EnGenius - DEVICE_MODEL := ENS620EXT - SOC := qcom-ipq4018 - DEVICE_DTS_CONFIG := config@4 - BLOCKSIZE := 64k - PAGESIZE := 256 - BOARD_NAME := ENS620EXT - VENDOR_ID := 0x0101 - PRODUCT_ID := 0x79 - PRODUCT_ID_NEW := 0xA4 - DATECODE := 190507 - FW_VER := 3.1.2 - FW_VER_NEW := 3.5.6 - CW_VER := 1.8.99 - IMAGE_SIZE := 21312k - KERNEL_SIZE := 5120k - FILESYSTEMS := squashfs - IMAGES += factory_30.bin factory_35.bin - IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | check-size | append-metadata - IMAGE/factory_30.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | check-size | SenaoFW $$$$(PRODUCT_ID) $$$$(FW_VER) - IMAGE/factory_35.bin := qsdk-ipq-factory-nor | check-size | SenaoFW $$$$(PRODUCT_ID_NEW) $$$$(FW_VER_NEW) -endef -TARGET_DEVICES += engenius_ens620ext - -define Device/ezviz_cs-w3-wd1200g-eup - $(call Device/FitImage) - DEVICE_VENDOR := EZVIZ - DEVICE_MODEL := CS-W3-WD1200G - DEVICE_VARIANT := EUP - DEVICE_DTS_CONFIG := config@4 - IMAGE_SIZE := 14848k - SOC := qcom-ipq4018 - IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | \ - append-metadata - DEVICE_PACKAGES := -kmod-ath10k-ct kmod-ath10k-ct-smallbuffers \ - ipq-wifi-ezviz_cs-w3-wd1200g-eup -endef -TARGET_DEVICES += ezviz_cs-w3-wd1200g-eup - -define Device/glinet_gl-ap1300 - $(call Device/FitImage) - $(call Device/UbiFit) - DEVICE_VENDOR := GL.iNet - DEVICE_MODEL := GL-AP1300 - SOC := qcom-ipq4018 - DEVICE_DTS_CONFIG := config@ap.dk01.1-c2 - BLOCKSIZE := 128k - PAGESIZE := 2048 - IMAGE_SIZE := 131072k - KERNEL_INSTALL := 1 - DEVICE_PACKAGES := ipq-wifi-glinet_gl-ap1300 -endef -TARGET_DEVICES += glinet_gl-ap1300 - -define Device/glinet_gl-b1300 - $(call Device/FitImage) - DEVICE_VENDOR := GL.iNet - DEVICE_MODEL := GL-B1300 - BOARD_NAME := gl-b1300 - SOC := qcom-ipq4029 - KERNEL_SIZE := 4096k - IMAGE_SIZE := 26624k - IMAGE/sysupgrade.bin := append-kernel |append-rootfs | pad-rootfs | append-metadata -endef -TARGET_DEVICES += glinet_gl-b1300 - -define Device/glinet_gl-s1300 - $(call Device/FitImage) - DEVICE_VENDOR := GL.iNet - DEVICE_MODEL := GL-S1300 - SOC := qcom-ipq4029 - KERNEL_SIZE := 4096k - IMAGE_SIZE := 26624k - IMAGES := sysupgrade.bin - IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata - DEVICE_PACKAGES := ipq-wifi-glinet_gl-s1300 kmod-fs-ext4 kmod-mmc kmod-spi-dev -endef -TARGET_DEVICES += glinet_gl-s1300 - -define Device/linksys_ea6350v3 - # The Linksys EA6350v3 has a uboot bootloader that does not - # support either booting lzma kernel images nor booting UBI - # partitions. This uboot, however, supports raw kernel images and - # gzipped images. - # - # As for the time of writing this, the device will boot the kernel - # from a fixed address with a fixed length of 3MiB. Also, the - # device has a hard-coded kernel command line that requieres the - # rootfs and alt_rootfs to be in mtd11 and mtd13 respectively. - # Oh... and the kernel partition overlaps with the rootfs - # partition (the same for alt_kernel and alt_rootfs). - # - # If you are planing re-partitioning the device, you may want to - # keep those details in mind: - # 1. The kernel adresses you should honor are 0x00000000 and - # 0x02800000 respectively. - # 2. The kernel size (plus the dtb) cannot exceed 3.00MiB in size. - # 3. You can use 'zImage', but not a raw 'Image' packed with lzma. - # 4. The kernel command line from uboot is harcoded to boot with - # rootfs either in mtd11 or mtd13. - $(call Device/FitzImage) - DEVICE_VENDOR := Linksys - DEVICE_MODEL := EA6350 - DEVICE_VARIANT := v3 - SOC := qcom-ipq4018 - BLOCKSIZE := 128k - PAGESIZE := 2048 - KERNEL_SIZE := 3072k - IMAGE_SIZE := 37888k - UBINIZE_OPTS := -E 5 - IMAGES += factory.bin - IMAGE/factory.bin := append-kernel | append-uImage-fakehdr filesystem | pad-to $$$$(KERNEL_SIZE) | append-ubi | linksys-image type=EA6350v3 - DEVICE_PACKAGES := uboot-envtools -endef -TARGET_DEVICES += linksys_ea6350v3 - -define Device/linksys_ea8300 - $(call Device/FitzImage) - DEVICE_VENDOR := Linksys - DEVICE_MODEL := EA8300 - SOC := qcom-ipq4019 - KERNEL_SIZE := 3072k - IMAGE_SIZE := 87040k - BLOCKSIZE := 128k - PAGESIZE := 2048 - 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=EA8300 - DEVICE_PACKAGES := uboot-envtools ath10k-firmware-qca9888-ct ipq-wifi-linksys_ea8300 kmod-usb-ledtrig-usbport -endef -TARGET_DEVICES += linksys_ea8300 - -define Device/linksys_mr8300 - $(call Device/FitzImage) - DEVICE_VENDOR := Linksys - DEVICE_MODEL := MR8300 - SOC := qcom-ipq4019 - KERNEL_SIZE := 3072k - IMAGE_SIZE := 87040k - BLOCKSIZE := 128k - PAGESIZE := 2048 - 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=MR8300 - DEVICE_PACKAGES := uboot-envtools ath10k-firmware-qca9888-ct ipq-wifi-linksys_mr8300-v0 kmod-usb-ledtrig-usbport -endef -TARGET_DEVICES += linksys_mr8300 - -define Device/luma_wrtq-329acn - $(call Device/FitImage) - DEVICE_VENDOR := Luma Home - DEVICE_MODEL := WRTQ-329ACN - SOC := qcom-ipq4018 - DEVICE_PACKAGES := ipq-wifi-luma_wrtq-329acn kmod-ath3k kmod-eeprom-at24 kmod-i2c-gpio uboot-envtools - IMAGE_SIZE := 76632k - BLOCKSIZE := 128k - PAGESIZE := 2048 -endef -TARGET_DEVICES += luma_wrtq-329acn - -define Device/meraki_mr33 - $(call Device/FitImage) - DEVICE_VENDOR := Cisco Meraki - DEVICE_MODEL := MR33 - SOC := qcom-ipq4029 - BLOCKSIZE := 128k - PAGESIZE := 2048 - DEVICE_PACKAGES := -swconfig ath10k-firmware-qca9887-ct -endef -TARGET_DEVICES += meraki_mr33 - -define Device/mobipromo_cm520-79f - $(call Device/FitzImage) - $(call Device/UbiFit) - DEVICE_VENDOR := MobiPromo - DEVICE_MODEL := CM520-79F - SOC := qcom-ipq4019 - BLOCKSIZE := 128k - PAGESIZE := 2048 - DEVICE_PACKAGES := ipq-wifi-mobipromo_cm520-79f kmod-usb-ledtrig-usbport -endef -TARGET_DEVICES += mobipromo_cm520-79f - -define Device/netgear_ex61x0v2 - $(call Device/DniImage) - DEVICE_VENDOR := NETGEAR - DEVICE_DTS_CONFIG := config@4 - NETGEAR_BOARD_ID := EX6150v2series - NETGEAR_HW_ID := 29765285+16+0+128+2x2 - IMAGE_SIZE := 14400k - SOC := qcom-ipq4018 -endef - -define Device/netgear_ex6100v2 - $(call Device/netgear_ex61x0v2) - DEVICE_MODEL := EX6100 - DEVICE_VARIANT := v2 -endef -TARGET_DEVICES += netgear_ex6100v2 - -define Device/netgear_ex6150v2 - $(call Device/netgear_ex61x0v2) - DEVICE_MODEL := EX6150 - DEVICE_VARIANT := v2 -endef -TARGET_DEVICES += netgear_ex6150v2 - -define Device/openmesh_a42 - $(call Device/FitImageLzma) - DEVICE_VENDOR := OpenMesh - DEVICE_MODEL := A42 - SOC := qcom-ipq4018 - DEVICE_DTS_CONFIG := config@om.a42 - BLOCKSIZE := 64k - KERNEL = kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb | pad-to $$(BLOCKSIZE) - IMAGE_SIZE := 15616k - IMAGES += factory.bin - IMAGE/factory.bin := append-rootfs | pad-rootfs | openmesh-image ce_type=A42 - IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | sysupgrade-tar rootfs=$$$$@ | append-metadata - DEVICE_PACKAGES := uboot-envtools -endef -TARGET_DEVICES += openmesh_a42 - -define Device/openmesh_a62 - $(call Device/FitImageLzma) - DEVICE_VENDOR := OpenMesh - DEVICE_MODEL := A62 - SOC := qcom-ipq4019 - DEVICE_DTS_CONFIG := config@om.a62 - BLOCKSIZE := 64k - KERNEL = kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb | pad-to $$(BLOCKSIZE) - IMAGE_SIZE := 15552k - IMAGES += factory.bin - IMAGE/factory.bin := append-rootfs | pad-rootfs | openmesh-image ce_type=A62 - IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | sysupgrade-tar rootfs=$$$$@ | append-metadata - DEVICE_PACKAGES := ath10k-firmware-qca9888-ct uboot-envtools -endef -TARGET_DEVICES += openmesh_a62 - -define Device/plasmacloud_pa1200 - $(call Device/FitImageLzma) - DEVICE_VENDOR := Plasma Cloud - DEVICE_MODEL := PA1200 - SOC := qcom-ipq4018 - DEVICE_DTS_CONFIG := config@pc.pa1200 - BLOCKSIZE := 64k - KERNEL = kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb | pad-to $$(BLOCKSIZE) - IMAGE_SIZE := 15616k - IMAGES += factory.bin - IMAGE/factory.bin := append-rootfs | pad-rootfs | openmesh-image ce_type=PA1200 - IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | sysupgrade-tar rootfs=$$$$@ | append-metadata - DEVICE_PACKAGES := uboot-envtools ipq-wifi-plasmacloud-pa1200 -endef -TARGET_DEVICES += plasmacloud_pa1200 - -define Device/plasmacloud_pa2200 - $(call Device/FitImageLzma) - DEVICE_VENDOR := Plasma Cloud - DEVICE_MODEL := PA2200 - SOC := qcom-ipq4019 - DEVICE_DTS_CONFIG := config@pc.pa2200 - BLOCKSIZE := 64k - KERNEL = kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb | pad-to $$(BLOCKSIZE) - IMAGE_SIZE := 15552k - IMAGES += factory.bin - IMAGE/factory.bin := append-rootfs | pad-rootfs | openmesh-image ce_type=PA2200 - IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | sysupgrade-tar rootfs=$$$$@ | append-metadata - DEVICE_PACKAGES := ath10k-firmware-qca9888-ct ipq-wifi-plasmacloud-pa2200 uboot-envtools -endef -TARGET_DEVICES += plasmacloud_pa2200 - -define Device/qcom_ap-dk01.1-c1 - DEVICE_VENDOR := Qualcomm Atheros - DEVICE_MODEL := AP-DK01.1 - DEVICE_VARIANT := C1 - BOARD_NAME := ap-dk01.1-c1 - SOC := qcom-ipq4019 - DEVICE_DTS := qcom-ipq4019-ap.dk01.1-c1 - KERNEL_INSTALL := 1 - KERNEL_SIZE := 4096k - IMAGE_SIZE := 26624k - $(call Device/FitImage) - IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | append-metadata -endef -TARGET_DEVICES += qcom_ap-dk01.1-c1 - -define Device/qcom_ap-dk04.1-c1 - $(call Device/FitImage) - $(call Device/UbiFit) - DEVICE_VENDOR := Qualcomm Atheros - DEVICE_MODEL := AP-DK04.1 - DEVICE_VARIANT := C1 - SOC := qcom-ipq4019 - DEVICE_DTS := qcom-ipq4019-ap.dk04.1-c1 - KERNEL_INSTALL := 1 - KERNEL_SIZE := 4048k - BLOCKSIZE := 128k - PAGESIZE := 2048 - BOARD_NAME := ap-dk04.1-c1 -endef -TARGET_DEVICES += qcom_ap-dk04.1-c1 - -define Device/qxwlan_e2600ac-c1 - $(call Device/FitImage) - DEVICE_VENDOR := Qxwlan - DEVICE_MODEL := E2600AC - DEVICE_VARIANT := C1 - BOARD_NAME := e2600ac-c1 - SOC := qcom-ipq4019 - KERNEL_SIZE := 4096k - IMAGE_SIZE := 31232k - IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata - DEVICE_PACKAGES := ipq-wifi-qxwlan_e2600ac -endef -TARGET_DEVICES += qxwlan_e2600ac-c1 - -define Device/qxwlan_e2600ac-c2 - $(call Device/FitImage) - $(call Device/UbiFit) - DEVICE_VENDOR := Qxwlan - DEVICE_MODEL := E2600AC - DEVICE_VARIANT := C2 - SOC := qcom-ipq4019 - KERNEL_INSTALL := 1 - BLOCKSIZE := 128k - PAGESIZE := 2048 - DEVICE_PACKAGES := ipq-wifi-qxwlan_e2600ac -endef -TARGET_DEVICES += qxwlan_e2600ac-c2 - -define Device/unielec_u4019-32m - $(call Device/FitImage) - DEVICE_VENDOR := Unielec - DEVICE_MODEL := U4019 - DEVICE_VARIANT := 32M - BOARD_NAME := u4019-32m - SOC := qcom-ipq4019 - KERNEL_SIZE := 4096k - IMAGE_SIZE := 31232k - IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata -endef -TARGET_DEVICES += unielec_u4019-32m - -define Device/zyxel_nbg6617 - $(call Device/FitImageLzma) - DEVICE_VENDOR := ZyXEL - DEVICE_MODEL := NBG6617 - SOC := qcom-ipq4018 - KERNEL_SIZE := 4096k - ROOTFS_SIZE := 24960k - RAS_BOARD := NBG6617 - RAS_ROOTFS_SIZE := 19840k - RAS_VERSION := "$(VERSION_DIST) $(REVISION)" - IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata - IMAGES += factory.bin -# The ZyXEL firmware allows flashing thru the web-gui only when the rootfs is -# at least as large as the one of the initial firmware image (not the current -# one on the device). This only applies to the Web-UI, the bootlaoder ignores -# this minimum-size. However, the larger image can be flashed both ways. - IMAGE/factory.bin := append-rootfs | pad-rootfs | pad-to 64k | check-size $$$$(ROOTFS_SIZE) | zyxel-ras-image separate-kernel - IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | check-size $$$$(ROOTFS_SIZE) | sysupgrade-tar rootfs=$$$$@ | append-metadata - DEVICE_PACKAGES := uboot-envtools kmod-usb-ledtrig-usbport -endef -TARGET_DEVICES += zyxel_nbg6617 - -define Device/zyxel_wre6606 - $(call Device/FitImage) - DEVICE_VENDOR := ZyXEL - DEVICE_MODEL := WRE6606 - DEVICE_DTS_CONFIG := config@4 - SOC := qcom-ipq4018 - IMAGE_SIZE := 13184k - IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata | check-size - DEVICE_PACKAGES := -kmod-ath10k-ct kmod-ath10k-ct-smallbuffers -endef -TARGET_DEVICES += zyxel_wre6606 +include $(SUBTARGET).mk $(eval $(call BuildImage)) diff --git a/target/linux/ipq40xx/image/generic.mk b/target/linux/ipq40xx/image/generic.mk new file mode 100644 index 0000000000..9cd50e23ff --- /dev/null +++ b/target/linux/ipq40xx/image/generic.mk @@ -0,0 +1,809 @@ + +DEVICE_VARS += NETGEAR_BOARD_ID NETGEAR_HW_ID +DEVICE_VARS += RAS_BOARD RAS_ROOTFS_SIZE RAS_VERSION +DEVICE_VARS += WRGG_DEVNAME WRGG_SIGNATURE + +define Device/FitImage + KERNEL_SUFFIX := -fit-uImage.itb + KERNEL = kernel-bin | gzip | fit gzip $$(DTS_DIR)/$$(DEVICE_DTS).dtb + KERNEL_NAME := Image +endef + +define Device/FitImageLzma + KERNEL_SUFFIX := -fit-uImage.itb + KERNEL = kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb + KERNEL_NAME := Image +endef + +define Device/FitzImage + KERNEL_SUFFIX := -fit-zImage.itb + KERNEL = kernel-bin | fit none $$(DTS_DIR)/$$(DEVICE_DTS).dtb + KERNEL_NAME := zImage +endef + +define Device/UbiFit + KERNEL_IN_UBI := 1 + IMAGES := nand-factory.ubi nand-sysupgrade.bin + IMAGE/nand-factory.ubi := append-ubi + IMAGE/nand-sysupgrade.bin := sysupgrade-tar | append-metadata +endef + +define Device/DniImage + $(call Device/FitzImage) + NETGEAR_BOARD_ID := + NETGEAR_HW_ID := + IMAGES += factory.img + IMAGE/factory.img := append-kernel | pad-offset 64k 64 | append-uImage-fakehdr filesystem | append-rootfs | pad-rootfs | netgear-dni + IMAGE/sysupgrade.bin := append-kernel | pad-offset 64k 64 | append-uImage-fakehdr filesystem | \ + append-rootfs | pad-rootfs | append-metadata | check-size +endef + +define Build/append-rootfshdr + mkimage -A $(LINUX_KARCH) \ + -O linux -T filesystem \ + -C lzma -a $(KERNEL_LOADADDR) -e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \ + -n root.squashfs -d $(IMAGE_ROOTFS) $@.new + dd if=$@.new bs=64 count=1 >> $(IMAGE_KERNEL) +endef + +define Build/mkmylofw_32m + $(eval device_id=$(word 1,$(1))) + $(eval revision=$(word 2,$(1))) + + let \ + size="$$(stat -c%s $@)" \ + pad="$(subst k,* 1024,$(BLOCKSIZE))" \ + pad="(pad - (size % pad)) % pad" \ + newsize='size + pad'; \ + $(STAGING_DIR_HOST)/bin/mkmylofw \ + -B WPE72 -i 0x11f6:$(device_id):0x11f6:$(device_id) -r $(revision) \ + -s 0x2000000 -p0x180000:$$newsize:al:0x80208000:"OpenWrt":$@ \ + $@.new + @mv $@.new $@ +endef + +define Build/qsdk-ipq-factory-nand-askey + $(TOPDIR)/scripts/mkits-qsdk-ipq-image.sh $@.its\ + askey_kernel $(IMAGE_KERNEL) \ + askey_fs $(IMAGE_ROOTFS) \ + ubifs $@ + PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage -f $@.its $@.new + @mv $@.new $@ +endef + +define Build/SenaoFW + -$(STAGING_DIR_HOST)/bin/mksenaofw \ + -n $(BOARD_NAME) -r $(VENDOR_ID) -p $(1) \ + -c $(DATECODE) -w $(2) -x $(CW_VER) -t 0 \ + -e $@ \ + -o $@.new + @cp $@.new $@ +endef + +define Build/wrgg-image + mkwrggimg -i $@ \ + -o $@.new \ + -d "$(WRGG_DEVNAME)" \ + -s "$(WRGG_SIGNATURE)" \ + -v "" -m "" -B "" + mv $@.new $@ +endef + +define Device/8dev_habanero-dvk + $(call Device/FitImageLzma) + DEVICE_VENDOR := 8devices + DEVICE_MODEL := Habanero DVK + IMAGE_SIZE := 30976k + SOC := qcom-ipq4019 + DEVICE_PACKAGES := ipq-wifi-8dev_habanero-dvk + IMAGE/sysupgrade.bin := append-kernel | pad-to 64k | append-rootfs | pad-rootfs | append-metadata | check-size +endef +TARGET_DEVICES += 8dev_habanero-dvk + +define Device/8dev_jalapeno-common + $(call Device/FitImage) + $(call Device/UbiFit) + BLOCKSIZE := 128k + PAGESIZE := 2048 + SOC := qcom-ipq4018 +endef + +define Device/8dev_jalapeno + $(call Device/8dev_jalapeno-common) + DEVICE_VENDOR := 8devices + DEVICE_MODEL := Jalapeno +endef +TARGET_DEVICES += 8dev_jalapeno + +define Device/alfa-network_ap120c-ac + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := ALFA Network + DEVICE_MODEL := AP120C-AC + SOC := qcom-ipq4018 + DEVICE_PACKAGES := kmod-usb-acm \ + kmod-tpm-i2c-atmel uboot-envtools + BLOCKSIZE := 128k + PAGESIZE := 2048 + IMAGE_SIZE := 65536k + IMAGES := nand-factory.bin nand-sysupgrade.bin + IMAGE/nand-factory.bin := append-ubi | qsdk-ipq-factory-nand +endef +TARGET_DEVICES += alfa-network_ap120c-ac + +define Device/aruba_glenmorangie + $(call Device/FitImageLzma) + DEVICE_VENDOR := Aruba + SOC := qcom-ipq4029 + DEVICE_PACKAGES := ipq-wifi-aruba_ap-303 +endef + +define Device/aruba_ap-303 + $(call Device/aruba_glenmorangie) + DEVICE_MODEL := AP-303 + DEVICE_PACKAGES += uboot-envtools +endef +TARGET_DEVICES += aruba_ap-303 + +define Device/aruba_ap-303h + $(call Device/aruba_glenmorangie) + DEVICE_MODEL := AP-303H +endef +TARGET_DEVICES += aruba_ap-303h + +define Device/aruba_ap-365 + $(call Device/aruba_glenmorangie) + DEVICE_MODEL := AP-365 + DEVICE_PACKAGES += kmod-hwmon-ad7418 uboot-envtools +endef +TARGET_DEVICES += aruba_ap-365 + +define Device/asus_map-ac2200 + $(call Device/FitImageLzma) + DEVICE_VENDOR := ASUS + DEVICE_MODEL := Lyra (MAP-AC2200) + SOC := qcom-ipq4019 + DEVICE_PACKAGES := ath10k-firmware-qca9888-ct kmod-ath3k +endef +TARGET_DEVICES += asus_map-ac2200 + +define Device/asus_rt-ac58u + $(call Device/FitImageLzma) + DEVICE_VENDOR := ASUS + DEVICE_MODEL := RT-AC58U + SOC := qcom-ipq4018 + BLOCKSIZE := 128k + PAGESIZE := 2048 + DTB_SIZE := 65536 + IMAGE_SIZE := 20439364 + FILESYSTEMS := squashfs +# Someone - in their infinite wisdom - decided to put the firmware +# version in front of the image name \03\00\00\04 => Version 3.0.0.4 +# Since u-boot works with strings we either need another fixup step +# to add a version... or we are very careful not to add '\0' into that +# string and call it a day.... Yeah, we do the latter! + UIMAGE_NAME:=$(shell echo -e '\03\01\01\01RT-AC58U') + DEVICE_PACKAGES := -kmod-ath10k-ct kmod-ath10k-ct-smallbuffers \ + kmod-usb-ledtrig-usbport +endef +TARGET_DEVICES += asus_rt-ac58u + +define Device/avm_fritzbox-4040 + $(call Device/FitImageLzma) + DEVICE_VENDOR := AVM + DEVICE_MODEL := FRITZ!Box 4040 + SOC := qcom-ipq4018 + BOARD_NAME := fritz4040 + IMAGE_SIZE := 29056k + UBOOT_PATH := $(STAGING_DIR_IMAGE)/uboot-fritz4040.bin + UBOOT_PARTITION_SIZE := 524288 + IMAGES += eva.bin + IMAGE/eva.bin := append-uboot | pad-to $$$$(UBOOT_PARTITION_SIZE) | append-kernel | append-rootfs | pad-rootfs + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata | check-size + DEVICE_PACKAGES := fritz-tffs fritz-caldata +endef +TARGET_DEVICES += avm_fritzbox-4040 + +define Device/avm_fritzbox-7530 + $(call Device/FitImageLzma) + DEVICE_VENDOR := AVM + DEVICE_MODEL := FRITZ!Box 7530 + SOC := qcom-ipq4019 + DEVICE_PACKAGES := fritz-caldata fritz-tffs-nand +endef +TARGET_DEVICES += avm_fritzbox-7530 + +define Device/avm_fritzrepeater-1200 + $(call Device/FitImageLzma) + DEVICE_VENDOR := AVM + DEVICE_MODEL := FRITZ!Repeater 1200 + SOC := qcom-ipq4019 + DEVICE_PACKAGES := fritz-caldata fritz-tffs-nand ipq-wifi-avm_fritzrepeater-1200 +endef +TARGET_DEVICES += avm_fritzrepeater-1200 + +define Device/avm_fritzrepeater-3000 + $(call Device/FitImageLzma) + DEVICE_VENDOR := AVM + DEVICE_MODEL := FRITZ!Repeater 3000 + SOC := qcom-ipq4019 + DEVICE_PACKAGES := ath10k-firmware-qca9984-ct fritz-caldata fritz-tffs-nand +endef +TARGET_DEVICES += avm_fritzrepeater-3000 + +define Device/buffalo_wtr-m2133hp + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := Buffalo + DEVICE_MODEL := WTR-M2133HP + SOC := qcom-ipq4019 + DEVICE_PACKAGES := uboot-envtools ath10k-firmware-qca9984-ct ipq-wifi-buffalo_wtr-m2133hp + BLOCKSIZE := 128k + PAGESIZE := 2048 +endef +TARGET_DEVICES += buffalo_wtr-m2133hp + +define Device/cellc_rtl30vw + KERNEL_SUFFIX := -fit-uImage.itb + KERNEL_INITRAMFS = kernel-bin | gzip | fit gzip $$(DTS_DIR)/$$(DEVICE_DTS).dtb + KERNEL = kernel-bin | gzip | fit gzip $$(DTS_DIR)/$$(DEVICE_DTS).dtb | uImage lzma | pad-to 2048 + KERNEL_NAME := Image + KERNEL_IN_UBI := + IMAGES := nand-factory.bin nand-sysupgrade.bin + IMAGE/nand-factory.bin := append-rootfshdr | append-ubi | qsdk-ipq-factory-nand-askey + IMAGE/nand-sysupgrade.bin := append-rootfshdr | sysupgrade-tar | append-metadata + DEVICE_VENDOR := Cell C + DEVICE_MODEL := RTL30VW + SOC := qcom-ipq4019 + DEVICE_DTS_CONFIG := config@5 + KERNEL_INSTALL := 1 + KERNEL_SIZE := 4096k + IMAGE_SIZE := 57344k + BLOCKSIZE := 128k + PAGESIZE := 2048 + DEVICE_PACKAGES := kmod-usb-net-qmi-wwan kmod-usb-serial-option uqmi ipq-wifi-cellc_rtl30vw +endef +TARGET_DEVICES += cellc_rtl30vw + +define Device/cilab_meshpoint-one + $(call Device/8dev_jalapeno-common) + DEVICE_VENDOR := Crisis Innovation Lab + DEVICE_MODEL := MeshPoint.One + DEVICE_PACKAGES := kmod-i2c-gpio kmod-iio-bmp280-i2c kmod-hwmon-ina2xx kmod-rtc-pcf2127 +endef +TARGET_DEVICES += cilab_meshpoint-one + +define Device/compex_wpj419 + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := Compex + DEVICE_MODEL := WPJ419 + SOC := qcom-ipq4019 + DEVICE_DTS_CONFIG := config@12 + KERNEL_INSTALL := 1 + BLOCKSIZE := 128k + PAGESIZE := 2048 + FILESYSTEMS := squashfs +endef +TARGET_DEVICES += compex_wpj419 + +define Device/compex_wpj428 + $(call Device/FitImage) + DEVICE_VENDOR := Compex + DEVICE_MODEL := WPJ428 + SOC := qcom-ipq4028 + DEVICE_DTS_CONFIG := config@4 + BLOCKSIZE := 64k + IMAGE_SIZE := 31232k + KERNEL_SIZE := 4096k + IMAGES += cpximg-6a04.bin + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata + IMAGE/cpximg-6a04.bin := append-kernel | append-rootfs | pad-rootfs | mkmylofw_32m 0x8A2 3 + DEVICE_PACKAGES := kmod-gpio-beeper +endef +TARGET_DEVICES += compex_wpj428 + +define Device/devolo_magic-2-wifi-next + $(call Device/FitImage) + DEVICE_VENDOR := devolo + DEVICE_MODEL := Magic 2 WiFi next + SOC := qcom-ipq4018 + KERNEL_SIZE := 4096k + + # If the bootloader sees 0xDEADC0DE and this trailer at the 64k boundary of a TFTP image + # it will bootm it, just like we want for the initramfs. + KERNEL_INITRAMFS := kernel-bin | gzip | fit gzip $$(DTS_DIR)/$$(DEVICE_DTS).dtb | pad-to 64k |\ + append-string -e '\xDE\xAD\xC0\xDE{"fl_initramfs":""}\x00' + + IMAGE_SIZE := 26624k + IMAGES := sysupgrade.bin + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata + DEVICE_PACKAGES := ipq-wifi-devolo_magic-2-wifi-next uboot-envtools +endef +TARGET_DEVICES += devolo_magic-2-wifi-next + +define Device/dlink_dap-2610 + $(call Device/FitImageLzma) + DEVICE_VENDOR := D-Link + DEVICE_MODEL := DAP-2610 + SOC := qcom-ipq4018 + DEVICE_DTS_CONFIG := config@ap.dk01.1-c1 + BLOCKSIZE := 64k + WRGG_DEVNAME := /dev/mtdblock/8 + WRGG_SIGNATURE := wapac30_dkbs_dap2610 + IMAGE_SIZE := 14080k + IMAGES += factory.bin + # Bootloader expects a special 160 byte header which is added by + # wrgg-image. + # Factory image size must be larger than 6MB, and size in wrgg header must + # match actual factory image size to be flashable from D-Link http server. + # Bootloader verifies checksum of wrgg image before booting, thus jffs2 + # cannot be part of the wrgg image. This is solved in the factory image by + # having the rootfs at the end of the image (without pad-rootfs). And in + # the sysupgrade image only the kernel is included in the wrgg checksum, + # but this is not flashable from the D-link http server. + # append-rootfs must start on an erase block boundary. + IMAGE/factory.bin := append-kernel | pad-offset 6144k 160 | append-rootfs | wrgg-image | check-size + IMAGE/sysupgrade.bin := append-kernel | wrgg-image | pad-to $$$$(BLOCKSIZE) | append-rootfs | pad-rootfs | check-size | append-metadata + DEVICE_PACKAGES := ipq-wifi-dlink_dap2610 +endef +TARGET_DEVICES += dlink_dap-2610 + +define Device/edgecore_ecw5211 + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := Edgecore + DEVICE_MODEL := ECW5211 + SOC := qcom-ipq4018 + BLOCKSIZE := 128k + PAGESIZE := 2048 + DEVICE_PACKAGES := kmod-tpm-i2c-atmel kmod-usb-acm uboot-envtools +endef +TARGET_DEVICES += edgecore_ecw5211 + +define Device/edgecore_oap100 + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := Edgecore + DEVICE_MODEL := OAP100 + SOC := qcom-ipq4019 + BLOCKSIZE := 128k + PAGESIZE := 2048 + IMAGES := nand-sysupgrade.bin + DEVICE_DTS_CONFIG := config@ap.dk07.1-c1 + DEVICE_PACKAGES := ipq-wifi-edgecore_oap100 kmod-usb-acm kmod-usb-net kmod-usb-net-cdc-qmi uqmi +endef +TARGET_DEVICES += edgecore_oap100 + +define Device/engenius_eap1300 + $(call Device/FitImage) + DEVICE_VENDOR := EnGenius + DEVICE_MODEL := EAP1300 + DEVICE_DTS_CONFIG := config@4 + BOARD_NAME := eap1300 + SOC := qcom-ipq4018 + KERNEL_SIZE := 5120k + IMAGE_SIZE := 25344k + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata +endef +TARGET_DEVICES += engenius_eap1300 + +define Device/engenius_eap2200 + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := EnGenius + DEVICE_MODEL := EAP2200 + SOC := qcom-ipq4019 + BLOCKSIZE := 128k + PAGESIZE := 2048 + DEVICE_PACKAGES := ath10k-firmware-qca9888-ct ipq-wifi-engenius_eap2200 -kmod-ath10k-ct kmod-ath10k-ct-smallbuffers +endef +TARGET_DEVICES += engenius_eap2200 + +define Device/engenius_emd1 + $(call Device/FitImage) + DEVICE_VENDOR := EnGenius + DEVICE_MODEL := EMD1 + DEVICE_DTS_CONFIG := config@4 + SOC := qcom-ipq4018 + IMAGE_SIZE := 30720k + IMAGES += factory.bin + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata + IMAGE/factory.bin := qsdk-ipq-factory-nor | check-size +endef +TARGET_DEVICES += engenius_emd1 + +define Device/engenius_emr3500 + $(call Device/FitImage) + DEVICE_VENDOR := EnGenius + DEVICE_MODEL := EMR3500 + DEVICE_DTS_CONFIG := config@4 + SOC := qcom-ipq4018 + KERNEL_SIZE := 4096k + IMAGE_SIZE := 30720k + IMAGES += factory.bin + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata + IMAGE/factory.bin := qsdk-ipq-factory-nor | check-size +endef +TARGET_DEVICES += engenius_emr3500 + +define Device/engenius_ens620ext + $(call Device/FitImage) + DEVICE_VENDOR := EnGenius + DEVICE_MODEL := ENS620EXT + SOC := qcom-ipq4018 + DEVICE_DTS_CONFIG := config@4 + BLOCKSIZE := 64k + PAGESIZE := 256 + BOARD_NAME := ENS620EXT + VENDOR_ID := 0x0101 + PRODUCT_ID := 0x79 + PRODUCT_ID_NEW := 0xA4 + DATECODE := 190507 + FW_VER := 3.1.2 + FW_VER_NEW := 3.5.6 + CW_VER := 1.8.99 + IMAGE_SIZE := 21312k + KERNEL_SIZE := 5120k + FILESYSTEMS := squashfs + IMAGES += factory_30.bin factory_35.bin + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | check-size | append-metadata + IMAGE/factory_30.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | check-size | SenaoFW $$$$(PRODUCT_ID) $$$$(FW_VER) + IMAGE/factory_35.bin := qsdk-ipq-factory-nor | check-size | SenaoFW $$$$(PRODUCT_ID_NEW) $$$$(FW_VER_NEW) +endef +TARGET_DEVICES += engenius_ens620ext + +define Device/ezviz_cs-w3-wd1200g-eup + $(call Device/FitImage) + DEVICE_VENDOR := EZVIZ + DEVICE_MODEL := CS-W3-WD1200G + DEVICE_VARIANT := EUP + DEVICE_DTS_CONFIG := config@4 + IMAGE_SIZE := 14848k + SOC := qcom-ipq4018 + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | \ + append-metadata + DEVICE_PACKAGES := -kmod-ath10k-ct kmod-ath10k-ct-smallbuffers \ + ipq-wifi-ezviz_cs-w3-wd1200g-eup +endef +TARGET_DEVICES += ezviz_cs-w3-wd1200g-eup + +define Device/glinet_gl-ap1300 + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := GL.iNet + DEVICE_MODEL := GL-AP1300 + SOC := qcom-ipq4018 + DEVICE_DTS_CONFIG := config@ap.dk01.1-c2 + BLOCKSIZE := 128k + PAGESIZE := 2048 + IMAGE_SIZE := 131072k + KERNEL_INSTALL := 1 + DEVICE_PACKAGES := ipq-wifi-glinet_gl-ap1300 +endef +TARGET_DEVICES += glinet_gl-ap1300 + +define Device/glinet_gl-b1300 + $(call Device/FitImage) + DEVICE_VENDOR := GL.iNet + DEVICE_MODEL := GL-B1300 + BOARD_NAME := gl-b1300 + SOC := qcom-ipq4029 + KERNEL_SIZE := 4096k + IMAGE_SIZE := 26624k + IMAGE/sysupgrade.bin := append-kernel |append-rootfs | pad-rootfs | append-metadata +endef +TARGET_DEVICES += glinet_gl-b1300 + +define Device/glinet_gl-s1300 + $(call Device/FitImage) + DEVICE_VENDOR := GL.iNet + DEVICE_MODEL := GL-S1300 + SOC := qcom-ipq4029 + KERNEL_SIZE := 4096k + IMAGE_SIZE := 26624k + IMAGES := sysupgrade.bin + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata + DEVICE_PACKAGES := ipq-wifi-glinet_gl-s1300 kmod-fs-ext4 kmod-mmc kmod-spi-dev +endef +TARGET_DEVICES += glinet_gl-s1300 + +define Device/linksys_ea6350v3 + # The Linksys EA6350v3 has a uboot bootloader that does not + # support either booting lzma kernel images nor booting UBI + # partitions. This uboot, however, supports raw kernel images and + # gzipped images. + # + # As for the time of writing this, the device will boot the kernel + # from a fixed address with a fixed length of 3MiB. Also, the + # device has a hard-coded kernel command line that requieres the + # rootfs and alt_rootfs to be in mtd11 and mtd13 respectively. + # Oh... and the kernel partition overlaps with the rootfs + # partition (the same for alt_kernel and alt_rootfs). + # + # If you are planing re-partitioning the device, you may want to + # keep those details in mind: + # 1. The kernel adresses you should honor are 0x00000000 and + # 0x02800000 respectively. + # 2. The kernel size (plus the dtb) cannot exceed 3.00MiB in size. + # 3. You can use 'zImage', but not a raw 'Image' packed with lzma. + # 4. The kernel command line from uboot is harcoded to boot with + # rootfs either in mtd11 or mtd13. + $(call Device/FitzImage) + DEVICE_VENDOR := Linksys + DEVICE_MODEL := EA6350 + DEVICE_VARIANT := v3 + SOC := qcom-ipq4018 + BLOCKSIZE := 128k + PAGESIZE := 2048 + KERNEL_SIZE := 3072k + IMAGE_SIZE := 37888k + UBINIZE_OPTS := -E 5 + IMAGES += factory.bin + IMAGE/factory.bin := append-kernel | append-uImage-fakehdr filesystem | pad-to $$$$(KERNEL_SIZE) | append-ubi | linksys-image type=EA6350v3 + DEVICE_PACKAGES := uboot-envtools +endef +TARGET_DEVICES += linksys_ea6350v3 + +define Device/linksys_ea8300 + $(call Device/FitzImage) + DEVICE_VENDOR := Linksys + DEVICE_MODEL := EA8300 + SOC := qcom-ipq4019 + KERNEL_SIZE := 3072k + IMAGE_SIZE := 87040k + BLOCKSIZE := 128k + PAGESIZE := 2048 + 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=EA8300 + DEVICE_PACKAGES := uboot-envtools ath10k-firmware-qca9888-ct ipq-wifi-linksys_ea8300 kmod-usb-ledtrig-usbport +endef +TARGET_DEVICES += linksys_ea8300 + +define Device/linksys_mr8300 + $(call Device/FitzImage) + DEVICE_VENDOR := Linksys + DEVICE_MODEL := MR8300 + SOC := qcom-ipq4019 + KERNEL_SIZE := 3072k + IMAGE_SIZE := 87040k + BLOCKSIZE := 128k + PAGESIZE := 2048 + 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=MR8300 + DEVICE_PACKAGES := uboot-envtools ath10k-firmware-qca9888-ct ipq-wifi-linksys_mr8300-v0 kmod-usb-ledtrig-usbport +endef +TARGET_DEVICES += linksys_mr8300 + +define Device/luma_wrtq-329acn + $(call Device/FitImage) + DEVICE_VENDOR := Luma Home + DEVICE_MODEL := WRTQ-329ACN + SOC := qcom-ipq4018 + DEVICE_PACKAGES := ipq-wifi-luma_wrtq-329acn kmod-ath3k kmod-eeprom-at24 kmod-i2c-gpio uboot-envtools + IMAGE_SIZE := 76632k + BLOCKSIZE := 128k + PAGESIZE := 2048 +endef +TARGET_DEVICES += luma_wrtq-329acn + +define Device/meraki_mr33 + $(call Device/FitImage) + DEVICE_VENDOR := Cisco Meraki + DEVICE_MODEL := MR33 + SOC := qcom-ipq4029 + BLOCKSIZE := 128k + PAGESIZE := 2048 + DEVICE_PACKAGES := -swconfig ath10k-firmware-qca9887-ct +endef +TARGET_DEVICES += meraki_mr33 + +define Device/mobipromo_cm520-79f + $(call Device/FitzImage) + $(call Device/UbiFit) + DEVICE_VENDOR := MobiPromo + DEVICE_MODEL := CM520-79F + SOC := qcom-ipq4019 + BLOCKSIZE := 128k + PAGESIZE := 2048 + DEVICE_PACKAGES := ipq-wifi-mobipromo_cm520-79f kmod-usb-ledtrig-usbport +endef +TARGET_DEVICES += mobipromo_cm520-79f + +define Device/netgear_ex61x0v2 + $(call Device/DniImage) + DEVICE_VENDOR := NETGEAR + DEVICE_DTS_CONFIG := config@4 + NETGEAR_BOARD_ID := EX6150v2series + NETGEAR_HW_ID := 29765285+16+0+128+2x2 + IMAGE_SIZE := 14400k + SOC := qcom-ipq4018 +endef + +define Device/netgear_ex6100v2 + $(call Device/netgear_ex61x0v2) + DEVICE_MODEL := EX6100 + DEVICE_VARIANT := v2 +endef +TARGET_DEVICES += netgear_ex6100v2 + +define Device/netgear_ex6150v2 + $(call Device/netgear_ex61x0v2) + DEVICE_MODEL := EX6150 + DEVICE_VARIANT := v2 +endef +TARGET_DEVICES += netgear_ex6150v2 + +define Device/openmesh_a42 + $(call Device/FitImageLzma) + DEVICE_VENDOR := OpenMesh + DEVICE_MODEL := A42 + SOC := qcom-ipq4018 + DEVICE_DTS_CONFIG := config@om.a42 + BLOCKSIZE := 64k + KERNEL = kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb | pad-to $$(BLOCKSIZE) + IMAGE_SIZE := 15616k + IMAGES += factory.bin + IMAGE/factory.bin := append-rootfs | pad-rootfs | openmesh-image ce_type=A42 + IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | sysupgrade-tar rootfs=$$$$@ | append-metadata + DEVICE_PACKAGES := uboot-envtools +endef +TARGET_DEVICES += openmesh_a42 + +define Device/openmesh_a62 + $(call Device/FitImageLzma) + DEVICE_VENDOR := OpenMesh + DEVICE_MODEL := A62 + SOC := qcom-ipq4019 + DEVICE_DTS_CONFIG := config@om.a62 + BLOCKSIZE := 64k + KERNEL = kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb | pad-to $$(BLOCKSIZE) + IMAGE_SIZE := 15552k + IMAGES += factory.bin + IMAGE/factory.bin := append-rootfs | pad-rootfs | openmesh-image ce_type=A62 + IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | sysupgrade-tar rootfs=$$$$@ | append-metadata + DEVICE_PACKAGES := ath10k-firmware-qca9888-ct uboot-envtools +endef +TARGET_DEVICES += openmesh_a62 + +define Device/plasmacloud_pa1200 + $(call Device/FitImageLzma) + DEVICE_VENDOR := Plasma Cloud + DEVICE_MODEL := PA1200 + SOC := qcom-ipq4018 + DEVICE_DTS_CONFIG := config@pc.pa1200 + BLOCKSIZE := 64k + KERNEL = kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb | pad-to $$(BLOCKSIZE) + IMAGE_SIZE := 15616k + IMAGES += factory.bin + IMAGE/factory.bin := append-rootfs | pad-rootfs | openmesh-image ce_type=PA1200 + IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | sysupgrade-tar rootfs=$$$$@ | append-metadata + DEVICE_PACKAGES := uboot-envtools ipq-wifi-plasmacloud-pa1200 +endef +TARGET_DEVICES += plasmacloud_pa1200 + +define Device/plasmacloud_pa2200 + $(call Device/FitImageLzma) + DEVICE_VENDOR := Plasma Cloud + DEVICE_MODEL := PA2200 + SOC := qcom-ipq4019 + DEVICE_DTS_CONFIG := config@pc.pa2200 + BLOCKSIZE := 64k + KERNEL = kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb | pad-to $$(BLOCKSIZE) + IMAGE_SIZE := 15552k + IMAGES += factory.bin + IMAGE/factory.bin := append-rootfs | pad-rootfs | openmesh-image ce_type=PA2200 + IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | sysupgrade-tar rootfs=$$$$@ | append-metadata + DEVICE_PACKAGES := ath10k-firmware-qca9888-ct ipq-wifi-plasmacloud-pa2200 uboot-envtools +endef +TARGET_DEVICES += plasmacloud_pa2200 + +define Device/qcom_ap-dk01.1-c1 + DEVICE_VENDOR := Qualcomm Atheros + DEVICE_MODEL := AP-DK01.1 + DEVICE_VARIANT := C1 + BOARD_NAME := ap-dk01.1-c1 + SOC := qcom-ipq4019 + DEVICE_DTS := qcom-ipq4019-ap.dk01.1-c1 + KERNEL_INSTALL := 1 + KERNEL_SIZE := 4096k + IMAGE_SIZE := 26624k + $(call Device/FitImage) + IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | append-metadata +endef +TARGET_DEVICES += qcom_ap-dk01.1-c1 + +define Device/qcom_ap-dk04.1-c1 + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := Qualcomm Atheros + DEVICE_MODEL := AP-DK04.1 + DEVICE_VARIANT := C1 + SOC := qcom-ipq4019 + DEVICE_DTS := qcom-ipq4019-ap.dk04.1-c1 + KERNEL_INSTALL := 1 + KERNEL_SIZE := 4048k + BLOCKSIZE := 128k + PAGESIZE := 2048 + BOARD_NAME := ap-dk04.1-c1 +endef +TARGET_DEVICES += qcom_ap-dk04.1-c1 + +define Device/qxwlan_e2600ac-c1 + $(call Device/FitImage) + DEVICE_VENDOR := Qxwlan + DEVICE_MODEL := E2600AC + DEVICE_VARIANT := C1 + BOARD_NAME := e2600ac-c1 + SOC := qcom-ipq4019 + KERNEL_SIZE := 4096k + IMAGE_SIZE := 31232k + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata + DEVICE_PACKAGES := ipq-wifi-qxwlan_e2600ac +endef +TARGET_DEVICES += qxwlan_e2600ac-c1 + +define Device/qxwlan_e2600ac-c2 + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := Qxwlan + DEVICE_MODEL := E2600AC + DEVICE_VARIANT := C2 + SOC := qcom-ipq4019 + KERNEL_INSTALL := 1 + BLOCKSIZE := 128k + PAGESIZE := 2048 + DEVICE_PACKAGES := ipq-wifi-qxwlan_e2600ac +endef +TARGET_DEVICES += qxwlan_e2600ac-c2 + +define Device/unielec_u4019-32m + $(call Device/FitImage) + DEVICE_VENDOR := Unielec + DEVICE_MODEL := U4019 + DEVICE_VARIANT := 32M + BOARD_NAME := u4019-32m + SOC := qcom-ipq4019 + KERNEL_SIZE := 4096k + IMAGE_SIZE := 31232k + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata +endef +TARGET_DEVICES += unielec_u4019-32m + +define Device/zyxel_nbg6617 + $(call Device/FitImageLzma) + DEVICE_VENDOR := ZyXEL + DEVICE_MODEL := NBG6617 + SOC := qcom-ipq4018 + KERNEL_SIZE := 4096k + ROOTFS_SIZE := 24960k + RAS_BOARD := NBG6617 + RAS_ROOTFS_SIZE := 19840k + RAS_VERSION := "$(VERSION_DIST) $(REVISION)" + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata + IMAGES += factory.bin +# The ZyXEL firmware allows flashing thru the web-gui only when the rootfs is +# at least as large as the one of the initial firmware image (not the current +# one on the device). This only applies to the Web-UI, the bootlaoder ignores +# this minimum-size. However, the larger image can be flashed both ways. + IMAGE/factory.bin := append-rootfs | pad-rootfs | pad-to 64k | check-size $$$$(ROOTFS_SIZE) | zyxel-ras-image separate-kernel + IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | check-size $$$$(ROOTFS_SIZE) | sysupgrade-tar rootfs=$$$$@ | append-metadata + DEVICE_PACKAGES := uboot-envtools kmod-usb-ledtrig-usbport +endef +TARGET_DEVICES += zyxel_nbg6617 + +define Device/zyxel_wre6606 + $(call Device/FitImage) + DEVICE_VENDOR := ZyXEL + DEVICE_MODEL := WRE6606 + DEVICE_DTS_CONFIG := config@4 + SOC := qcom-ipq4018 + IMAGE_SIZE := 13184k + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata | check-size + DEVICE_PACKAGES := -kmod-ath10k-ct kmod-ath10k-ct-smallbuffers +endef +TARGET_DEVICES += zyxel_wre6606 + +$(eval $(call BuildImage)) From 0798b13d7df0deafd005b14d52420c4f480d146e Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Sun, 3 Jan 2021 16:27:08 -0800 Subject: [PATCH 02/34] libusb: update to 1.0.24 Signed-off-by: Rosen Penev --- package/libs/libusb/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/libs/libusb/Makefile b/package/libs/libusb/Makefile index 6ce33d3f86..26f7360166 100644 --- a/package/libs/libusb/Makefile +++ b/package/libs/libusb/Makefile @@ -8,14 +8,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libusb -PKG_VERSION:=1.0.22 -PKG_RELEASE:=2 +PKG_VERSION:=1.0.24 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=\ https://github.com/libusb/libusb/releases/download/v$(PKG_VERSION) \ @SF/$(PKG_NAME) -PKG_HASH:=75aeb9d59a4fdb800d329a545c2e6799f732362193b465ea198f2aa275518157 +PKG_HASH:=7efd2685f7b327326dcfb85cee426d9b871fd70e22caa15bb68d595ce2a2b12a PKG_INSTALL:=1 PKG_BUILD_PARALLEL:=0 From 3d2dab566050b6d3090b6336d6ea8e60d620fa24 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Sun, 3 Jan 2021 16:27:09 -0800 Subject: [PATCH 03/34] libusb: cleanup PKG_ variables Reordered for consistency between packages. Fixed license information. Change PKG_BUILD_PARALLEL to 1. This is no longer a problem.1 Signed-off-by: Rosen Penev --- package/libs/libusb/Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/package/libs/libusb/Makefile b/package/libs/libusb/Makefile index 26f7360166..d8380ee67d 100644 --- a/package/libs/libusb/Makefile +++ b/package/libs/libusb/Makefile @@ -17,11 +17,12 @@ PKG_SOURCE_URL:=\ @SF/$(PKG_NAME) PKG_HASH:=7efd2685f7b327326dcfb85cee426d9b871fd70e22caa15bb68d595ce2a2b12a -PKG_INSTALL:=1 -PKG_BUILD_PARALLEL:=0 -PKG_LICENSE:=LGPL-2.1 +PKG_MAINTAINER:= Felix Fietkau +PKG_LICENSE:=LGPL-2.1-or-later +PKG_LICENSE_FILES:=COPYING -PKG_MAINTAINER := Felix Fietkau +PKG_INSTALL:=1 +PKG_BUILD_PARALLEL:=1 include $(INCLUDE_DIR)/package.mk From 43539a6aabbee86b5fb2fbb5c36c477407d98765 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Sun, 3 Jan 2021 16:27:10 -0800 Subject: [PATCH 04/34] libusb: make InstallDev explicit Helps to see what actually gets installed. Signed-off-by: Rosen Penev --- package/libs/libusb/Makefile | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/package/libs/libusb/Makefile b/package/libs/libusb/Makefile index d8380ee67d..e931536339 100644 --- a/package/libs/libusb/Makefile +++ b/package/libs/libusb/Makefile @@ -46,12 +46,17 @@ CONFIGURE_ARGS += \ --disable-log define Build/InstallDev - $(CP) $(PKG_INSTALL_DIR)/* $(1)/ + $(INSTALL_DIR) $(1)/usr/include/libusb-1.0 + $(CP) $(PKG_INSTALL_DIR)/usr/include/libusb-1.0/libusb.h $(1)/usr/include/libusb-1.0/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libusb-1.0.* $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libusb-1.0.pc $(1)/usr/lib/pkgconfig/ endef define Package/libusb-1.0/install $(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libusb*.so.* $(1)/usr/lib/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libusb-1.0.so.* $(1)/usr/lib/ endef $(eval $(call BuildPackage,libusb-1.0)) From b6461e46549b613480c1516d42527a6756ec7df7 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 30 Oct 2020 13:58:29 +0100 Subject: [PATCH 05/34] ipq40xx: arm: compressed: add appended DTB section This adds a appended_dtb section to the ARM decompressor linker script. This allows using the existing ARM zImage appended DTB support for appending a DTB to the raw ELF kernel. Its size is set to 1MB max to match the zImage appended DTB size limit. To use it to pass the DTB to the kernel, objcopy is used: objcopy --set-section-flags=.appended_dtb=alloc,contents \ --update-section=.appended_dtb=.dtb vmlinux This is based off the following patch: https://github.com/openwrt/openwrt/commit/c063e27e02a9dcac0e7f5877fb154e58fa3e1a69 Signed-off-by: Robert Marko --- ...-compressed-add-appended-DTB-section.patch | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 target/linux/ipq40xx/patches-5.4/301-arm-compressed-add-appended-DTB-section.patch diff --git a/target/linux/ipq40xx/patches-5.4/301-arm-compressed-add-appended-DTB-section.patch b/target/linux/ipq40xx/patches-5.4/301-arm-compressed-add-appended-DTB-section.patch new file mode 100644 index 0000000000..7e6184fc73 --- /dev/null +++ b/target/linux/ipq40xx/patches-5.4/301-arm-compressed-add-appended-DTB-section.patch @@ -0,0 +1,48 @@ +From 0843a61d6913bdac8889eb048ed89f7903059787 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 30 Oct 2020 13:36:31 +0100 +Subject: [PATCH] arm: compressed: add appended DTB section + +This adds a appended_dtb section to the ARM decompressor +linker script. + +This allows using the existing ARM zImage appended DTB support for +appending a DTB to the raw ELF kernel. + +Its size is set to 1MB max to match the zImage appended DTB size limit. + +To use it to pass the DTB to the kernel, objcopy is used: + +objcopy --set-section-flags=.appended_dtb=alloc,contents \ + --update-section=.appended_dtb=.dtb vmlinux + +This is based off the following patch: +https://github.com/openwrt/openwrt/commit/c063e27e02a9dcac0e7f5877fb154e58fa3e1a69 + +Signed-off-by: Robert Marko +--- + arch/arm/boot/compressed/vmlinux.lds.S | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/arch/arm/boot/compressed/vmlinux.lds.S ++++ b/arch/arm/boot/compressed/vmlinux.lds.S +@@ -93,6 +93,13 @@ SECTIONS + + _edata = .; + ++ .appended_dtb : { ++ /* leave space for appended DTB */ ++ . += 0x100000; ++ } ++ ++ _edata_dtb = .; ++ + /* + * The image_end section appears after any additional loadable sections + * that the linker may decide to insert in the binary image. Having +@@ -132,4 +139,4 @@ SECTIONS + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + } +-ASSERT(_edata_real == _edata, "error: zImage file size is incorrect"); ++ASSERT(_edata_real == _edata_dtb, "error: zImage file size is incorrect"); From 10d057f84ad13853089b312bb61ecd042ebbb712 Mon Sep 17 00:00:00 2001 From: John Thomson Date: Fri, 23 Oct 2020 19:49:26 +1000 Subject: [PATCH 06/34] ipq40xx: kernel compressed boot: reset watchdog countdown If the watchdog is enabled, set the timeout to 30 seconds before decompress is started. Mikrotik ipq40xx devices running with RouterBoot have the SoC watchdog enabled and running with a timeout that does not allow time for the kernel to decompress and manage the watchdog. On ipq40xx RouterBoot TFTP boot the watchdog countdown is reset before: Jumping to kernel Signed-off-by: John Thomson --- ...d-set-ipq40xx-watchdog-to-allow-boot.patch | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 target/linux/ipq40xx/patches-5.4/302-arm-compressed-set-ipq40xx-watchdog-to-allow-boot.patch diff --git a/target/linux/ipq40xx/patches-5.4/302-arm-compressed-set-ipq40xx-watchdog-to-allow-boot.patch b/target/linux/ipq40xx/patches-5.4/302-arm-compressed-set-ipq40xx-watchdog-to-allow-boot.patch new file mode 100644 index 0000000000..71618a40f2 --- /dev/null +++ b/target/linux/ipq40xx/patches-5.4/302-arm-compressed-set-ipq40xx-watchdog-to-allow-boot.patch @@ -0,0 +1,66 @@ +From 11d6a6128a5a07c429941afc202b6e62a19771be Mon Sep 17 00:00:00 2001 +From: John Thomson +Date: Fri, 23 Oct 2020 19:42:36 +1000 +Subject: [PATCH 2/2] arm: compressed: set ipq40xx watchdog to allow boot + +For IPQ40XX systems where the SoC watchdog is activated before linux, +the watchdog timer may be too small for linux to finish uncompress, +boot, and watchdog management start. +If the watchdog is enabled, set the timeout for it to 30 seconds. +The functionality and offsets were copied from: +drivers/watchdog/qcom-wdt.c qcom_wdt_set_timeout & qcom_wdt_start +The watchdog memory address was taken from: +arch/arm/boot/dts/qcom-ipq4019.dtsi + +This was required on Mikrotik IPQ40XX consumer hardware using Mikrotik's +RouterBoot bootloader. + +Signed-off-by: John Thomson +--- + arch/arm/boot/compressed/head.S | 35 +++++++++++++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + +--- a/arch/arm/boot/compressed/head.S ++++ b/arch/arm/boot/compressed/head.S +@@ -599,6 +599,41 @@ not_relocated: mov r0, #0 + bic r4, r4, #1 + blne cache_on + ++/* Set the Qualcom IPQ40xx watchdog timeout to 30 seconds ++ * if it is enabled, so that there is time for kernel ++ * to decompress, boot, and take over the watchdog. ++ * data and functionality from drivers/watchdog/qcom-wdt.c ++ * address from arch/arm/boot/dts/qcom-ipq4019.dtsi ++ */ ++#ifdef CONFIG_ARCH_IPQ40XX ++watchdog_set: ++ /* offsets: ++ * 0x04 reset (=1 resets countdown) ++ * 0x08 enable (=0 disables) ++ * 0x0c status (=1 when SoC was reset by watchdog) ++ * 0x10 bark (=timeout warning in ticks) ++ * 0x14 bite (=timeout reset in ticks) ++ * clock rate is 1<<15 hertz ++ */ ++ .equ watchdog, 0x0b017000 @Store watchdog base address ++ movw r0, #:lower16:watchdog ++ movt r0, #:upper16:watchdog ++ ldr r1, [r0, #0x08] @Get enabled? ++ cmp r1, #1 @If not enabled, do not change ++ bne watchdog_finished ++ mov r1, #0 ++ str r1, [r0, #0x08] @Disable the watchdog ++ mov r1, #1 ++ str r1, [r0, #0x04] @Pet the watchdog ++ mov r1, #30 @30 seconds timeout ++ lsl r1, r1, #15 @converted to ticks ++ str r1, [r0, #0x10] @Set the bark timeout ++ str r1, [r0, #0x14] @Set the bite timeout ++ mov r1, #1 ++ str r1, [r0, #0x08] @Enable the watchdog ++watchdog_finished: ++#endif /* CONFIG_ARCH_IPQ40XX */ ++ + /* + * The C runtime environment should now be setup sufficiently. + * Set up some pointers, and start decompressing. From b779da27ef4a1bf47c8ae67809ecae99ba3ffa08 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Thu, 12 Nov 2020 18:13:26 +0100 Subject: [PATCH 07/34] ipq40xx: add MikroTik subtarget MikroTik devices require the use of raw vmlinux out of the self extracting compressed kernels. They also require 4K sectors, kernel2minor, partition parser as well as RouterBoard platform drivers. So in order to not add unnecessary code to the generic sub target lets introduce a MikroTik sub target. Signed-off-by: Robert Marko --- target/linux/ipq40xx/Makefile | 2 +- target/linux/ipq40xx/image/mikrotik.mk | 0 target/linux/ipq40xx/mikrotik/target.mk | 4 ++++ 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 target/linux/ipq40xx/image/mikrotik.mk create mode 100644 target/linux/ipq40xx/mikrotik/target.mk diff --git a/target/linux/ipq40xx/Makefile b/target/linux/ipq40xx/Makefile index 4d9b2debca..43b1fcb0f9 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 +SUBTARGETS:=generic mikrotik KERNEL_PATCHVER:=5.4 KERNEL_TESTING_PATCHVER:=5.4 diff --git a/target/linux/ipq40xx/image/mikrotik.mk b/target/linux/ipq40xx/image/mikrotik.mk new file mode 100644 index 0000000000..e69de29bb2 diff --git a/target/linux/ipq40xx/mikrotik/target.mk b/target/linux/ipq40xx/mikrotik/target.mk new file mode 100644 index 0000000000..4530a90985 --- /dev/null +++ b/target/linux/ipq40xx/mikrotik/target.mk @@ -0,0 +1,4 @@ +BOARDNAME:=MikroTik +FEATURES += minor +KERNEL_IMAGES:=vmlinux +IMAGES_DIR:=compressed From 30a92f55de8cd61da8fd0a5df4a8612c5d459d94 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 30 Oct 2020 18:39:04 +0100 Subject: [PATCH 08/34] ipq40xx: mikrotik: enable CONFIG_MTD_ROUTERBOOT_PARTS This enables the new MikroTik specific partition parser. This avoids manually specifying the MikroTik specific partitions as they can be detected by their magic values. Signed-off-by: Robert Marko --- target/linux/ipq40xx/mikrotik/config-default | 1 + 1 file changed, 1 insertion(+) create mode 100644 target/linux/ipq40xx/mikrotik/config-default diff --git a/target/linux/ipq40xx/mikrotik/config-default b/target/linux/ipq40xx/mikrotik/config-default new file mode 100644 index 0000000000..ac1113bdc2 --- /dev/null +++ b/target/linux/ipq40xx/mikrotik/config-default @@ -0,0 +1 @@ +CONFIG_MTD_ROUTERBOOT_PARTS=y From 01848890880e3da8267d5ccec559740a57763eb0 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 30 Oct 2020 18:40:27 +0100 Subject: [PATCH 09/34] ipq40xx: mikrotik: enable MikroTik NOR parser Needed for SPI-NOR based MikroTik IPQ40xx devices like hAP ac2. Signed-off-by: Robert Marko --- target/linux/ipq40xx/mikrotik/config-default | 1 + 1 file changed, 1 insertion(+) diff --git a/target/linux/ipq40xx/mikrotik/config-default b/target/linux/ipq40xx/mikrotik/config-default index ac1113bdc2..01b9b4562d 100644 --- a/target/linux/ipq40xx/mikrotik/config-default +++ b/target/linux/ipq40xx/mikrotik/config-default @@ -1 +1,2 @@ CONFIG_MTD_ROUTERBOOT_PARTS=y +CONFIG_MTD_SPLIT_MINOR_FW=y From f4fdd8609c1e7c407956f1f65aa7f8d154af9875 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 30 Oct 2020 18:42:37 +0100 Subject: [PATCH 10/34] ipq40xx: mikrotik: enable MikroTik platform driver This enables the MikroTik platform driver, it enables us to parse valuable info from hard_config including WLAN calibration data extraction from sysfs. Signed-off-by: Robert Marko --- target/linux/ipq40xx/mikrotik/config-default | 2 ++ 1 file changed, 2 insertions(+) diff --git a/target/linux/ipq40xx/mikrotik/config-default b/target/linux/ipq40xx/mikrotik/config-default index 01b9b4562d..147217380c 100644 --- a/target/linux/ipq40xx/mikrotik/config-default +++ b/target/linux/ipq40xx/mikrotik/config-default @@ -1,2 +1,4 @@ +CONFIG_MIKROTIK=y +CONFIG_MIKROTIK_RB_SYSFS=y CONFIG_MTD_ROUTERBOOT_PARTS=y CONFIG_MTD_SPLIT_MINOR_FW=y From 430154135106cbea6816a379774fd250a72a7063 Mon Sep 17 00:00:00 2001 From: Hans Dedecker Date: Wed, 13 Jan 2021 20:06:23 +0100 Subject: [PATCH 11/34] odhcp6c: fix routing loop on point-to-point links 53f07e9 ra: fix routing loop on point to point links 2b6959d ra: align ifindex resolving Tested-by: Karl Vogel Signed-off-by: Hans Dedecker --- package/network/ipv6/odhcp6c/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/network/ipv6/odhcp6c/Makefile b/package/network/ipv6/odhcp6c/Makefile index a52d3a3504..c9eaaedb19 100644 --- a/package/network/ipv6/odhcp6c/Makefile +++ b/package/network/ipv6/odhcp6c/Makefile @@ -12,9 +12,9 @@ PKG_RELEASE:=16 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/odhcp6c.git -PKG_SOURCE_DATE:=2020-12-26 -PKG_SOURCE_VERSION:=eac1961983b8e7a74c494feedcb878170b135072 -PKG_MIRROR_HASH:=3d026e66a57082d15a848357fdd94b8332d4916aa5a3251f72c3f83da3d6513e +PKG_SOURCE_DATE:=2021-01-09 +PKG_SOURCE_VERSION:=53f07e90b7f1da6977143a488dd5cb73a33b233b +PKG_MIRROR_HASH:=ad3665b611d19177996771b11df28d92f066b0125484ea3bdfc0b3185c14f90e PKG_MAINTAINER:=Hans Dedecker PKG_LICENSE:=GPL-2.0 From e857b097678d660c1121cd7ab8e753bb864970ab Mon Sep 17 00:00:00 2001 From: Hans Dedecker Date: Wed, 13 Jan 2021 20:14:47 +0100 Subject: [PATCH 12/34] netifd: fix IPv6 routing loop on point-to-point links c00c833 interface-ip: add unreachable route if address is offlink e71909c interface-ip: coding style fixes Tested-by: Karl Vogel Signed-off-by: Hans Dedecker --- package/network/config/netifd/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/network/config/netifd/Makefile b/package/network/config/netifd/Makefile index f34896b7ec..7061456b08 100644 --- a/package/network/config/netifd/Makefile +++ b/package/network/config/netifd/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/netifd.git -PKG_SOURCE_DATE:=2021-01-05 -PKG_SOURCE_VERSION:=0c8343968108f960b4eaafe4713453c5453bc6a0 -PKG_MIRROR_HASH:=613c432bbec93e067432646161ab1ba6a433ab7e4e8d3992cf3696128717ae36 +PKG_SOURCE_DATE:=2021-01-09 +PKG_SOURCE_VERSION:=c00c8335d6188daa326ecfe5a62da15a9b9987e1 +PKG_MIRROR_HASH:=c740e51e0cec13eec336ba1c7a643db3b64a9a2235f8c1b73a566cb89e841190 PKG_MAINTAINER:=Felix Fietkau PKG_LICENSE:=GPL-2.0 From f13b623f5e53a72b65f45cbaf56c73df35e70ed2 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Sun, 3 Jan 2021 16:28:43 -0800 Subject: [PATCH 13/34] mbedtls: update to 2.16.9 Signed-off-by: Rosen Penev --- package/libs/mbedtls/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/libs/mbedtls/Makefile b/package/libs/mbedtls/Makefile index 79650b594a..43cc8b05b7 100644 --- a/package/libs/mbedtls/Makefile +++ b/package/libs/mbedtls/Makefile @@ -8,13 +8,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mbedtls -PKG_VERSION:=2.16.8 +PKG_VERSION:=2.16.9 PKG_RELEASE:=1 PKG_USE_MIPS16:=0 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/ARMmbed/mbedtls/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=fe9e3b15c3375943bdfebbbb20dd6b4f1147b3b5d926248bd835d73247407430 +PKG_HASH:=fc17ff7d8c11d08f23ae2800a18269408ad2c24ea6bb8b9363e41a01c2425697 PKG_BUILD_PARALLEL:=1 PKG_LICENSE:=GPL-2.0-or-later From eaca08ab58afafc506f7313f2c1a763a11d9367e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 13 Jan 2021 14:14:11 +0100 Subject: [PATCH 14/34] firmware-utils: bcm4908img: tool adding BCM4908 image tail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flashing image with BCM4908 CFE bootloader requires specific firmware format. It needs 20 extra bytes with magic numbers and CRC32 appended. This tools allows appending such a tail to the specified image and also verifying CRC32 of existing BCM4908 image. Signed-off-by: RafaÅ‚ MiÅ‚ecki --- tools/firmware-utils/Makefile | 1 + tools/firmware-utils/src/bcm4908img.c | 379 ++++++++++++++++++++++++++ 2 files changed, 380 insertions(+) create mode 100644 tools/firmware-utils/src/bcm4908img.c diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile index a8c6ab4f65..055082593b 100644 --- a/tools/firmware-utils/Makefile +++ b/tools/firmware-utils/Makefile @@ -27,6 +27,7 @@ define Host/Compile $(call cc,add_header) $(call cc,addpattern) $(call cc,asustrx) + $(call cc,bcm4908img,-Wall) $(call cc,bcm4908kernel,-Wall) $(call cc,buffalo-enc buffalo-lib,-Wall) $(call cc,buffalo-tag buffalo-lib,-Wall) diff --git a/tools/firmware-utils/src/bcm4908img.c b/tools/firmware-utils/src/bcm4908img.c new file mode 100644 index 0000000000..86a187b146 --- /dev/null +++ b/tools/firmware-utils/src/bcm4908img.c @@ -0,0 +1,379 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2021 RafaÅ‚ MiÅ‚ecki + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(__BYTE_ORDER) +#error "Unknown byte order" +#endif + +#if __BYTE_ORDER == __BIG_ENDIAN +#define cpu_to_le32(x) bswap_32(x) +#define le32_to_cpu(x) bswap_32(x) +#elif __BYTE_ORDER == __LITTLE_ENDIAN +#define cpu_to_le32(x) (x) +#define le32_to_cpu(x) (x) +#else +#error "Unsupported endianness" +#endif + +struct bcm4908img_tail { + uint32_t crc32; + uint32_t unk1; + uint32_t family; + uint32_t unk2; + uint32_t unk3; +}; + +char *pathname; +static size_t prefix_len; +static size_t suffix_len; + +static inline size_t bcm4908img_min(size_t x, size_t y) { + return x < y ? x : y; +} + +/************************************************** + * CRC32 + **************************************************/ + +static const uint32_t crc32_tbl[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; + +uint32_t bcm4908img_crc32(uint32_t crc, uint8_t *buf, size_t len) { + while (len) { + crc = crc32_tbl[(crc ^ *buf) & 0xff] ^ (crc >> 8); + buf++; + len--; + } + + return crc; +} + +/************************************************** + * Check + **************************************************/ + +static void bcm4908img_check_parse_options(int argc, char **argv) { + int c; + + while ((c = getopt(argc, argv, "p:s:")) != -1) { + switch (c) { + case 'p': + prefix_len = atoi(optarg); + break; + case 's': + suffix_len = atoi(optarg); + break; + } + } +} + +static int bcm4908img_check(int argc, char **argv) { + struct bcm4908img_tail tail; + struct stat st; + uint8_t buf[1024]; + uint32_t crc32; + size_t length; + size_t bytes; + FILE *fp; + int err = 0; + + if (argc < 3) { + fprintf(stderr, "No BCM4908 image pathname passed\n"); + err = -EINVAL; + goto out; + } + pathname = argv[2]; + + optind = 3; + bcm4908img_check_parse_options(argc, argv); + + if (stat(pathname, &st)) { + fprintf(stderr, "Failed to stat %s\n", pathname); + err = -EIO; + goto out; + } + + fp = fopen(pathname, "r"); + if (!fp) { + fprintf(stderr, "Failed to open %s\n", pathname); + err = -EACCES; + goto out; + } + + fseek(fp, prefix_len, SEEK_SET); + + crc32 = 0xffffffff; + length = st.st_size - prefix_len - sizeof(tail) - suffix_len; + while (length && (bytes = fread(buf, 1, bcm4908img_min(sizeof(buf), length), fp)) > 0) { + crc32 = bcm4908img_crc32(crc32, buf, bytes); + length -= bytes; + } + + if (length) { + fprintf(stderr, "Failed to read last %zd B of data from %s\n", length, pathname); + err = -EIO; + goto err_close; + } + + if (fread(&tail, 1, sizeof(tail), fp) != sizeof(tail)) { + fprintf(stderr, "Failed to read BCM4908 image tail\n"); + err = -EIO; + goto err_close; + } + + if (crc32 != le32_to_cpu(tail.crc32)) { + fprintf(stderr, "Invalid data crc32: 0x%08x instead of 0x%08x\n", crc32, le32_to_cpu(tail.crc32)); + err = -EPROTO; + goto err_close; + } + + printf("Found a valid BCM4908 image (crc: 0x%08x)\n", crc32); + +err_close: + fclose(fp); +out: + return err; +} + +/************************************************** + * Create + **************************************************/ + +static ssize_t bcm4908img_create_append_file(FILE *trx, const char *in_path, uint32_t *crc32) { + FILE *in; + size_t bytes; + ssize_t length = 0; + uint8_t buf[1024]; + + in = fopen(in_path, "r"); + if (!in) { + fprintf(stderr, "Failed to open %s\n", in_path); + return -EACCES; + } + + while ((bytes = fread(buf, 1, sizeof(buf), in)) > 0) { + if (fwrite(buf, 1, bytes, trx) != bytes) { + fprintf(stderr, "Failed to write %zu B to %s\n", bytes, pathname); + length = -EIO; + break; + } + *crc32 = bcm4908img_crc32(*crc32, buf, bytes); + length += bytes; + } + + fclose(in); + + return length; +} + +static ssize_t bcm4908img_create_append_zeros(FILE *trx, size_t length) { + uint8_t *buf; + + buf = malloc(length); + if (!buf) + return -ENOMEM; + memset(buf, 0, length); + + if (fwrite(buf, 1, length, trx) != length) { + fprintf(stderr, "Failed to write %zu B to %s\n", length, pathname); + free(buf); + return -EIO; + } + + free(buf); + + return length; +} + +static ssize_t bcm4908img_create_align(FILE *trx, size_t cur_offset, size_t alignment) { + if (cur_offset & (alignment - 1)) { + size_t length = alignment - (cur_offset % alignment); + return bcm4908img_create_append_zeros(trx, length); + } + + return 0; +} + +static int bcm4908img_create(int argc, char **argv) { + struct bcm4908img_tail tail = { + .unk1 = cpu_to_le32(0x5732), + .family = cpu_to_le32(0x4908), + .unk2 = cpu_to_le32(0x03), + .unk3 = cpu_to_le32(0x02), + }; + uint32_t crc32 = 0xffffffff; + size_t cur_offset = 0; + ssize_t bytes; + FILE *fp; + int c; + int err = 0; + + if (argc < 3) { + fprintf(stderr, "No BCM4908 image pathname passed\n"); + err = -EINVAL; + goto out; + } + pathname = argv[2]; + + fp = fopen(pathname, "w+"); + if (!fp) { + fprintf(stderr, "Failed to open %s\n", pathname); + err = -EACCES; + goto out; + } + + optind = 3; + while ((c = getopt(argc, argv, "f:a:A:")) != -1) { + switch (c) { + case 'f': + bytes = bcm4908img_create_append_file(fp, optarg, &crc32); + if (bytes < 0) { + fprintf(stderr, "Failed to append file %s\n", optarg); + } else { + cur_offset += bytes; + } + break; + case 'a': + bytes = bcm4908img_create_align(fp, cur_offset, strtol(optarg, NULL, 0)); + if (bytes < 0) + fprintf(stderr, "Failed to append zeros\n"); + else + cur_offset += bytes; + break; + case 'A': + bytes = strtol(optarg, NULL, 0) - cur_offset; + if (bytes < 0) { + fprintf(stderr, "Current BCM4908 image length is 0x%zx, can't pad it with zeros to 0x%lx\n", cur_offset, strtol(optarg, NULL, 0)); + } else { + bytes = bcm4908img_create_append_zeros(fp, bytes); + if (bytes < 0) + fprintf(stderr, "Failed to append zeros\n"); + else + cur_offset += bytes; + } + break; + } + if (err) + goto err_close; + } + + tail.crc32 = cpu_to_le32(crc32); + + bytes = fwrite(&tail, 1, sizeof(tail), fp); + if (bytes != sizeof(tail)) { + fprintf(stderr, "Failed to write BCM4908 image tail to %s\n", pathname); + return -EIO; + } + +err_close: + fclose(fp); +out: + return err; +} + +/************************************************** + * Start + **************************************************/ + +static void usage() { + printf("Usage:\n"); + printf("\n"); + printf("Checking a BCM4908 image:\n"); + printf("\tbcm4908img check [options]\tcheck if images is valid\n"); + printf("\t-p prefix\t\t\tlength of custom header to skip (default: 0)\n"); + printf("\t-s suffix\t\t\tlength of custom tail to skip (default: 0)\n"); + printf("\n"); + printf("Creating a new BCM4908 image:\n"); + printf("\tbcm4908img create [options]\n"); + printf("\t-f file\t\t\t\tadd data from specified file\n"); + printf("\t-a alignment\t\t\tpad image with zeros to specified alignment\n"); + printf("\t-A offset\t\t\t\tappend zeros until reaching specified offset\n"); +} + +int main(int argc, char **argv) { + if (argc > 1) { + if (!strcmp(argv[1], "check")) + return bcm4908img_check(argc, argv); + else if (!strcmp(argv[1], "create")) + return bcm4908img_create(argc, argv); + } + + usage(); + return 0; +} From f559b89bd0341a0ab3979484ca4c52205343f090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 15 Jan 2021 10:44:12 +0100 Subject: [PATCH 15/34] bcm63xx-cfe: enable package for bcm4908 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bcm4908 target needs to include cferam images in firmware files too Signed-off-by: RafaÅ‚ MiÅ‚ecki --- package/kernel/bcm63xx-cfe/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/kernel/bcm63xx-cfe/Makefile b/package/kernel/bcm63xx-cfe/Makefile index bdc8b2cc76..3eada4bab2 100644 --- a/package/kernel/bcm63xx-cfe/Makefile +++ b/package/kernel/bcm63xx-cfe/Makefile @@ -17,9 +17,9 @@ include $(INCLUDE_DIR)/package.mk define Package/bcm63xx-cfe SECTION:=boot CATEGORY:=Boot Loaders - DEPENDS:=@TARGET_bcm63xx + DEPENDS:=@(TARGET_bcm4908||TARGET_bcm63xx) TITLE:=bcm63xx-cfe - DEFAULT:=y if TARGET_bcm63xx + DEFAULT:=y endef define Package/bcm63xx-cfe/description From a8a17fd22326f0d1aa7644556eea6010e0779afe Mon Sep 17 00:00:00 2001 From: David Bauer Date: Fri, 15 Jan 2021 02:15:12 +0100 Subject: [PATCH 16/34] rockchip: use stable MAC-address for NanoPi R2S The NanoPi R2S does not have a board specific MAC address written inside e.g. an EEPROM, hence why it is randomly generated on first boot. The issue with that however is the lack of a driver for the PRNG. It often results to the same MAC address used on multiple boards by default, as urngd is not active at this early stage resulting in low available entropy. There is however a semi-unique identifier available to us, which is the CID of the used SD card. It is unique to each SD card, hence we can use it to generate the MAC address used for LAN and WAN. Signed-off-by: David Bauer --- .../rockchip/armv8/base-files/etc/board.d/02_network | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network index e129fd6a67..48133c81a1 100755 --- a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network +++ b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network @@ -17,6 +17,13 @@ rockchip_setup_interfaces() esac } +nanopi_r2s_generate_mac() +{ + local sd_hash=$(sha256sum /sys/devices/platform/ff500000.dwmmc/mmc_host/mmc0/mmc0:*/cid) + local mac_base=$(macaddr_canonicalize "$(echo "${sd_hash}" | dd bs=1 count=12 2>/dev/null)") + echo "$(macaddr_unsetbit_mc "$(macaddr_setbit_la "${mac_base}")")" +} + rockchip_setup_macs() { local board="$1" @@ -26,7 +33,7 @@ rockchip_setup_macs() case "$board" in friendlyarm,nanopi-r2s) - wan_mac=$(macaddr_random) + wan_mac=$(nanopi_r2s_generate_mac) lan_mac=$(macaddr_add "$wan_mac" +1) ;; esac From 99f50a75351f91f82485e05f6efaa3c36aa5f79f Mon Sep 17 00:00:00 2001 From: David Bauer Date: Sat, 16 Jan 2021 20:08:35 +0100 Subject: [PATCH 17/34] ath79: rename UniFi AC kernel1 partition These devices do not run Ubiquiti AirOS. Rename the partition to the name used by other UniFi devices with vendor dualboot support. Signed-off-by: David Bauer --- target/linux/ath79/dts/qca9563_ubnt_unifiac.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/ath79/dts/qca9563_ubnt_unifiac.dtsi b/target/linux/ath79/dts/qca9563_ubnt_unifiac.dtsi index 14532d3b7f..85f13c1473 100644 --- a/target/linux/ath79/dts/qca9563_ubnt_unifiac.dtsi +++ b/target/linux/ath79/dts/qca9563_ubnt_unifiac.dtsi @@ -79,7 +79,7 @@ }; partition@800000 { - label = "ubnt-airos"; + label = "kernel1"; reg = <0x800000 0x790000>; read-only; }; From 26d1e529f1e327d2702e71369718a23b7c675c0c Mon Sep 17 00:00:00 2001 From: Paul Spooren Date: Mon, 18 Jan 2021 09:07:22 -1000 Subject: [PATCH 18/34] include: update logo with better kerning Kerning seems to be very off-putting for some people so the logo designer thankfully updated guidelines to something which is now considered final. Signed-off-by: Paul Spooren --- include/logo.png | Bin 80437 -> 81750 bytes include/logo.svg | 730 +++++++++++++++++------------------------------ 2 files changed, 259 insertions(+), 471 deletions(-) diff --git a/include/logo.png b/include/logo.png index de2a2bd097eab3dfb82af6d1e3cb46943a031eab..bb208dd90590a273fa9b2b138f2d2b64cb3d7de1 100644 GIT binary patch literal 81750 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 z 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 T9Wu5N;J=4DM)zy9?4$n!WR%<> literal 80437 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⋙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%0Al4s~`d)Z*DLpEqQ0E{mEyIieC zBT}%tR%<~IAE>3Vdn$|C!CZ5QUeNQa1_}NFfBQTlc!o!bqD2Pt1yimT;sE6zmff{ z8DZ`@9uVLER54aROn&T#UnvUW?>L3MmkGp-Lnb6ag}hTC3n!<9^4YJeVJqvb z{hdazcO3_f+SNpHt0vBH1su;PZiIN{cvS1*{8*HDJ<$Tk~b6QFEtIv}m?FtTSECa}_ydJ$c62#>Y=OC&C>SJ515kDE|1Dd!X$|;69juO zFEoJLo~ShDR~z`ujPF|D#mm2?t?WYU{p?ZuGjCM=D{NvC>MfV)s2gz-y|^bqGvetA z{5YOKebuE))I|IKR|BUz_UP>0{uscHh1B2r5Y;=r&1pk`q#mq6qsT?YbJ=9}nfw$* w2i}vcL<{0p`BX@p63YgxQ4;EFL#?`Q@Uvde)e8uubb)|N9i{~>Q!)?z9|A!LMgRZ+ diff --git a/include/logo.svg b/include/logo.svg index 50628c89b9..ff4b8adfc7 100644 --- a/include/logo.svg +++ b/include/logo.svg @@ -5,58 +5,92 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" - id="svg5076" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="2000mm" + height="595.20099mm" + viewBox="0 0 2000.0002 595.20098" version="1.1" - viewBox="0 0 1020 283.64442" - height="283.64441mm" - width="1020mm"> + id="svg971" + inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)" + sodipodi:docname="logo.svg"> + id="defs965"> + clipPathUnits="userSpaceOnUse" + id="clipPath78"> + d="M 0,0 H 792 V 612 H 0 Z" + id="path76" /> + clipPathUnits="userSpaceOnUse" + id="clipPath106"> + d="M 0,0 H 792 V 612 H 0 Z" + id="path104" /> + clipPathUnits="userSpaceOnUse" + id="clipPath130"> + d="M 0,0 H 792 V 612 H 0 Z" + id="path128" /> + clipPathUnits="userSpaceOnUse" + id="clipPath154"> + d="M 0,0 H 792 V 612 H 0 Z" + id="path152" /> + clipPathUnits="userSpaceOnUse" + id="clipPath174"> + d="M 0,0 H 792 V 612 H 0 Z" + id="path172" /> + clipPathUnits="userSpaceOnUse" + id="clipPath194"> + d="M 0,0 H 792 V 612 H 0 Z" + id="path192" /> + + + + + id="metadata968"> @@ -68,541 +102,295 @@ + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(312.17635,44.559227)"> - - - - + id="g72" + transform="matrix(12.354182,0,0,-12.354182,-1687.2697,4281.0797)"> + id="g74" + clip-path="url(#clipPath78)"> + id="g80" + transform="translate(173.1753,319.1396)"> + d="m 0,0 c 0,-5.745 -4.627,-10.263 -10.545,-10.263 -5.918,0 -10.544,4.518 -10.544,10.263 0,5.771 4.626,10.367 10.544,10.367 C -4.627,10.367 0,5.771 0,0 m -3.685,0 c 0,3.995 -3.013,7.024 -6.86,7.024 -3.846,0 -6.859,-3.029 -6.859,-7.024 0,-3.995 3.013,-6.946 6.859,-6.946 3.847,0 6.86,2.95 6.86,6.946" + style="fill:#00ace2;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path82" /> + + + + + + + + + + id="g96" + transform="matrix(12.354182,0,0,-12.354182,1281.2351,460.31368)"> + d="M 0,0 H -2.851 L -7.854,12.874 -12.885,0 h -2.824 l -6.699,19.846 h 3.82 l 4.492,-13.109 5.138,13.109 h 2.179 L -1.641,6.737 2.851,19.846 h 3.846 z" + style="fill:#00ace2;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path98" /> - - - - - - + id="g100" + transform="matrix(12.354182,0,0,-12.354182,-1687.2697,4281.0797)"> + id="g102" + clip-path="url(#clipPath106)"> + id="g108" + transform="translate(255.7183,322.3774)"> + d="m 0,0 -0.188,-3.316 h -0.78 c -3.282,0 -4.789,-1.959 -4.789,-5.588 v -4.204 h -3.551 v 13.03 h 3.551 V -2.35 c 0.996,1.515 2.556,2.454 4.816,2.454 0.349,0 0.618,0 0.941,-0.104" + style="fill:#00ace2;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path110" /> + id="g112" + transform="translate(263.2698,314.0737)"> + d="m 0,0 c 0,-1.279 0.619,-1.985 1.695,-1.985 0.618,0 1.533,0.262 2.234,0.627 L 4.952,-4.23 C 3.553,-4.961 2.584,-5.197 1.455,-5.197 c -3.201,0 -5.004,1.776 -5.004,4.937 v 5.665 h -2.879 v 2.821 h 2.879 v 4.726 l 3.55,1.045 V 8.226 H 5.193 V 5.405 H 0 Z" + style="fill:#00ace2;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path114" /> + id="g116" + transform="matrix(12.354182,0,0,-12.354182,612.14009,549.73584)"> + d="M 0,0 H -0.799 L -1.549,2 -2.304,0 H -3.1 l -1.224,3.689 h 1.02 l 0.635,-1.99 0.795,1.99 h 0.65 l 0.79,-1.99 0.64,1.99 h 1.02 z" + style="fill:#002843;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path118" /> + id="g120" + transform="matrix(12.354182,0,0,-12.354182,674.30011,539.84385)"> + + + + id="g126" + clip-path="url(#clipPath130)"> + id="g132" + transform="translate(196.9004,302.0308)"> + d="M 0,0 -0.7,0.801 H -1.449 V 0 H -2.41 v 3.689 h 1.771 c 1,0 1.605,-0.573 1.605,-1.427 0,-0.549 -0.255,-0.991 -0.695,-1.238 L 1.206,0 Z m -0.675,1.602 c 0.4,0 0.73,0.262 0.73,0.66 0,0.388 -0.33,0.628 -0.73,0.628 H -1.449 V 1.604 Z" + style="fill:#002843;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path134" /> + id="g136" + transform="matrix(12.354182,0,0,-12.354182,820.47493,549.73584)"> + d="m 0,0 h -2.9 v 3.689 h 2.87 V 2.888 H -1.94 V 2.257 h 1.88 V 1.456 H -1.94 V 0.801 h 1.941 z" + style="fill:#002843;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path138" /> + id="g140" + transform="matrix(12.354182,0,0,-12.354182,886.62894,549.73584)"> + d="m 0,0 h -2.805 v 3.689 h 0.96 V 0.801 H 0 Z" + style="fill:#002843;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path142" /> + id="g144" + transform="matrix(12.354182,0,0,-12.354182,953.79261,549.73584)"> + + + + id="g150" + clip-path="url(#clipPath154)"> + id="g156" + transform="translate(219.3787,304.7295)"> + d="m 0,0 -0.94,-0.185 c -0.08,0.374 -0.34,0.481 -0.565,0.481 -0.225,0 -0.41,-0.111 -0.41,-0.316 0,-0.146 0.08,-0.238 0.245,-0.286 l 0.74,-0.228 c 0.625,-0.199 0.965,-0.481 0.965,-1.058 0,-0.83 -0.75,-1.18 -1.495,-1.18 -0.825,0 -1.495,0.422 -1.59,1.126 l 0.985,0.194 c 0.08,-0.364 0.304,-0.519 0.635,-0.519 0.28,0 0.45,0.126 0.45,0.321 0,0.145 -0.08,0.247 -0.29,0.3 l -0.705,0.199 c -0.575,0.16 -0.965,0.447 -0.965,1.044 0,0.752 0.609,1.165 1.44,1.165 0.79,0 1.375,-0.369 1.5,-1.058" + style="fill:#002843;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path158" /> + id="g160" + transform="translate(224.4026,304.7295)"> + d="m 0,0 -0.94,-0.185 c -0.08,0.374 -0.34,0.481 -0.565,0.481 -0.225,0 -0.41,-0.111 -0.41,-0.316 0,-0.146 0.08,-0.238 0.245,-0.286 l 0.74,-0.228 c 0.625,-0.199 0.965,-0.481 0.965,-1.058 0,-0.83 -0.75,-1.18 -1.495,-1.18 -0.825,0 -1.495,0.422 -1.591,1.126 l 0.986,0.194 c 0.08,-0.364 0.304,-0.519 0.635,-0.519 0.28,0 0.45,0.126 0.45,0.321 0,0.145 -0.08,0.247 -0.29,0.3 l -0.705,0.2 c -0.575,0.16 -0.965,0.446 -0.965,1.044 0,0.752 0.608,1.165 1.44,1.165 C -0.71,1.058 -0.125,0.689 0,0" + style="fill:#002843;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path162" /> + id="g164" + transform="matrix(12.354182,0,0,-12.354182,1170.9286,521.84896)"> + d="M 0,0 H 1.785 V -0.801 H 0 V -2.257 H -0.96 V 1.432 H 1.915 V 0.631 H 0 Z" + style="fill:#002843;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path166" /> + id="g168" + transform="matrix(12.354182,0,0,-12.354182,-1687.2697,4281.0797)"> + id="g170" + clip-path="url(#clipPath174)"> + id="g176" + transform="translate(238.2297,302.0308)"> - - - - - - - - - - - - - - - - - - - - - - - - + d="M 0,0 -0.7,0.801 H -1.45 V 0 h -0.96 v 3.689 h 1.77 c 1,0 1.605,-0.573 1.605,-1.427 C 0.965,1.713 0.71,1.271 0.27,1.024 L 1.205,0 Z m -0.675,1.602 c 0.4,0 0.73,0.262 0.73,0.66 0,0.388 -0.33,0.628 -0.73,0.628 H -1.45 V 1.604 Z" + style="fill:#002843;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path178" /> + id="g180" + transform="matrix(12.354182,0,0,-12.354182,1331.0682,549.73584)"> + d="m 0,0 h -2.9 v 3.689 h 2.87 V 2.888 H -1.94 V 2.257 h 1.88 V 1.456 H -1.94 V 0.801 H 0 Z" + style="fill:#002843;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path182" /> + id="g184" + transform="matrix(12.354182,0,0,-12.354182,1398.3947,549.73584)"> + + + + id="g190" + clip-path="url(#clipPath194)"> + id="g196" + transform="translate(254.0122,305.7197)"> + d="M 0,0 C 1.21,0 2.01,-0.739 2.01,-1.844 2.01,-2.95 1.211,-3.689 0,-3.689 H -1.695 V 0 Z m -0.01,-2.888 c 0.655,0 1.055,0.417 1.055,1.044 0,0.626 -0.4,1.043 -1.055,1.043 h -0.723 v -2.087 z" + style="fill:#002843;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path198" /> + id="g200" + transform="translate(262.0693,303.8706)"> - - - + d="m 0,0 c 0,-1.078 -0.91,-1.913 -2.03,-1.913 -1.12,0 -2.035,0.835 -2.035,1.913 0,1.077 0.91,1.917 2.035,1.917 C -0.905,1.917 0,1.073 0,0 m -0.965,0 c 0,0.606 -0.47,1.077 -1.066,1.077 -0.595,0 -1.065,-0.471 -1.065,-1.077 0,-0.607 0.47,-1.078 1.065,-1.078 0.596,0 1.066,0.466 1.066,1.078" + style="fill:#002843;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path202" /> + id="g204" + transform="matrix(12.354182,0,0,-12.354182,1629.3552,549.73584)"> + d="M 0,0 H -0.94 V 1.752 L -2.06,0.256 H -2.35 L -3.47,1.75 v -1.751 h -0.94 v 3.689 h 0.615 l 1.59,-2.17 1.59,2.17 H 0 Z" + style="fill:#002843;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path206" /> - + id="g208" + transform="matrix(12.354182,0,0,-12.354182,-1687.2697,4281.0797)"> + id="g210" + clip-path="url(#clipPath214)"> + id="g216" + transform="translate(271.6895,328.4058)"> - - - - - - - - - - - - - - - - + d="M 0,0 -0.99,1.042 H -1.398 V 0 h -0.455 v 2.468 h 0.95 c 0.533,0 0.856,-0.296 0.856,-0.712 0.008,-0.283 -0.169,-0.54 -0.441,-0.642 L 0.569,0 Z m -0.903,1.441 c 0.267,0 0.405,0.137 0.405,0.315 0,0.179 -0.141,0.311 -0.405,0.311 H -1.398 V 1.44 Z" + style="fill:#00ace2;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path218" /> + id="g220" + transform="translate(270.8284,327.209)"> - - - - - - - - - - - - - - - - - - - - - - - + d="m 0,0 c -1.307,0 -2.366,1.028 -2.367,2.296 0,1.269 1.059,2.298 2.366,2.298 1.307,0 2.366,-1.028 2.367,-2.296 V 2.297 C 2.365,1.029 1.306,0.002 0,0 m 0,4.269 c -1.122,0 -2.031,-0.883 -2.031,-1.972 0,-1.089 0.909,-1.971 2.031,-1.971 1.122,0 2.031,0.882 2.031,1.971 C 2.03,3.386 1.121,4.268 0,4.269 Z" + style="fill:#00ace2;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path222" /> + id="g224" + transform="translate(130.3613,326.9673)"> - - - - - - - - - - + d="m 0,0 c -1.713,0 -3.102,-1.348 -3.102,-3.011 0,-1.663 1.389,-3.011 3.102,-3.011 1.713,0 3.102,1.348 3.102,3.011 C 3.099,-1.35 1.712,-0.003 0,0" + style="fill:#00ace2;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path226" /> + id="g228" + transform="translate(111.3059,342.4536)"> + d="m 0,0 3.229,-3.134 c 4.051,3.933 9.653,6.36 15.826,6.36 6.174,0 11.776,-2.428 15.827,-6.36 L 38.111,0 C 33.236,4.732 26.494,7.682 19.055,7.682 11.617,7.682 4.875,4.732 0,0" + style="fill:#00ace2;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path230" /> + id="g232" + transform="translate(117.1301,336.7998)"> + d="m 0,0 3.229,-3.134 c 2.564,2.488 6.109,4.025 10.001,4.025 3.892,0 7.44,-1.537 10.004,-4.025 L 26.463,0 C 23.076,3.288 18.391,5.348 13.232,5.348 8.072,5.348 3.388,3.289 0,0" + style="fill:#00ace2;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path234" /> + id="g236" + transform="translate(122.9229,331.1763)"> + d="m 0,0 3.229,-3.134 c 2.326,2.253 6.093,2.253 8.419,0 L 14.877,0 C 12.905,1.915 10.228,2.988 7.438,2.98 4.558,2.98 1.93,1.844 0,0" + style="fill:#00ace2;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path238" /> + id="g240" + transform="translate(141.8201,332.0371)"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - + d="m 0,0 c 1.709,-2.274 2.722,-5.07 2.722,-8.081 0,-7.589 -6.362,-13.766 -14.181,-13.766 -7.818,0 -14.18,6.177 -14.18,13.766 0,3.011 1.013,5.807 2.722,8.081 l -3.26,3.165 c -2.533,-3.103 -4.021,-7.006 -4.021,-11.246 0,-10.017 8.42,-18.19 18.739,-18.19 10.32,0 18.739,8.173 18.739,18.19 0,4.24 -1.519,8.143 -4.02,11.246 z" + style="fill:#002843;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path242" /> From a141e7a00e3ad8442831ed87766451a6114afdf9 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Mon, 18 Jan 2021 21:57:05 +0100 Subject: [PATCH 19/34] at91bootstrap: Add PKG_MIRROR_HASH to fix download The referenced commit is gone, but we already have this file on our mirror, use that one by providing the correct mirror hash. I generated a tar.xz file with the given git commit hash using a random fork on github and it generated the same tar.xz file as found on our mirror so this looks correct. Signed-off-by: Hauke Mehrtens --- package/boot/at91bootstrap/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/package/boot/at91bootstrap/Makefile b/package/boot/at91bootstrap/Makefile index b0d466f7b9..f66472fa9c 100644 --- a/package/boot/at91bootstrap/Makefile +++ b/package/boot/at91bootstrap/Makefile @@ -14,6 +14,7 @@ PKG_RELEASE:=2 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/linux4sam/at91bootstrap.git +PKG_MIRROR_HASH:=06753d673756edc9753932db00f4e5b8c1f9fa7708337c4d6ce280573efb86b4 PKG_SOURCE_VERSION:=d96833a4b6680b237708eb4dc9f10708b9e709d8 PKG_BUILD_DIR = \ $(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) From 20a7c9d5c9d87595aa73ad39e95132df545a60ca Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Mon, 18 Jan 2021 21:57:10 +0100 Subject: [PATCH 20/34] uboot-at91: Add PKG_MIRROR_HASH to fix download The referenced commit is gone, but we already have this file on our mirror, use that one by providing the correct mirror hash. I generated a tar.xz file with the given git commit hash using a random fork on github and it generated the same tar.xz file as found on our mirror so this looks correct. Signed-off-by: Hauke Mehrtens --- package/boot/uboot-at91/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/package/boot/uboot-at91/Makefile b/package/boot/uboot-at91/Makefile index f2ad9562aa..a8a71239a3 100644 --- a/package/boot/uboot-at91/Makefile +++ b/package/boot/uboot-at91/Makefile @@ -12,6 +12,7 @@ PKG_RELEASE:=2 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/linux4sam/u-boot-at91.git +PKG_MIRROR_HASH:=4f106d215c01c4d024c4612bbd3ef189188d19abc1ab2cc316b257d308534feb PKG_SOURCE_VERSION:=0e1d1b6efb7f8e27c372279a906fcd2524df09da include $(INCLUDE_DIR)/u-boot.mk From e87c0d934c54d0b07caef1db3af170510acf3cfa Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Mon, 11 Jan 2021 00:33:07 +0100 Subject: [PATCH 21/34] dnsmasq: Update to version 2.83 This fixes the following security problems in dnsmasq: * CVE-2020-25681: Dnsmasq versions before 2.83 is susceptible to a heap-based buffer overflow in sort_rrset() when DNSSEC is used. This can allow a remote attacker to write arbitrary data into target device's memory that can lead to memory corruption and other unexpected behaviors on the target device. * CVE-2020-25682: Dnsmasq versions before 2.83 is susceptible to buffer overflow in extract_name() function due to missing length check, when DNSSEC is enabled. This can allow a remote attacker to cause memory corruption on the target device. * CVE-2020-25683: Dnsmasq version before 2.83 is susceptible to a heap-based buffer overflow when DNSSEC is enabled. A remote attacker, who can create valid DNS replies, could use this flaw to cause an overflow in a heap- allocated memory. This flaw is caused by the lack of length checks in rtc1035.c:extract_name(), which could be abused to make the code execute memcpy() with a negative size in get_rdata() and cause a crash in Dnsmasq, resulting in a Denial of Service. * CVE-2020-25684: A lack of proper address/port check implemented in Dnsmasq version < 2.83 reply_query function makes forging replies easier to an off-path attacker. * CVE-2020-25685: A lack of query resource name (RRNAME) checks implemented in Dnsmasq's versions before 2.83 reply_query function allows remote attackers to spoof DNS traffic that can lead to DNS cache poisoning. * CVE-2020-25686: Multiple DNS query requests for the same resource name (RRNAME) by Dnsmasq versions before 2.83 allows for remote attackers to spoof DNS traffic, using a birthday attack (RFC 5452), that can lead to DNS cache poisoning. * CVE-2020-25687: Dnsmasq versions before 2.83 is vulnerable to a heap-based buffer overflow with large memcpy in sort_rrset() when DNSSEC is enabled. A remote attacker, who can create valid DNS replies, could use this flaw to cause an overflow in a heap-allocated memory. This flaw is caused by the lack of length checks in rtc1035.c:extract_name(), which could be abused to make the code execute memcpy() with a negative size in sort_rrset() and cause a crash in dnsmasq, resulting in a Denial of Service. Signed-off-by: Hauke Mehrtens --- package/network/services/dnsmasq/Makefile | 6 +++--- .../patches/100-remove-old-runtime-kernel-support.patch | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package/network/services/dnsmasq/Makefile b/package/network/services/dnsmasq/Makefile index ba10ded333..7b5af1dd27 100644 --- a/package/network/services/dnsmasq/Makefile +++ b/package/network/services/dnsmasq/Makefile @@ -8,13 +8,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=dnsmasq -PKG_UPSTREAM_VERSION:=2.82 +PKG_UPSTREAM_VERSION:=2.83 PKG_VERSION:=$(subst test,~~test,$(subst rc,~rc,$(PKG_UPSTREAM_VERSION))) -PKG_RELEASE:=10 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_UPSTREAM_VERSION).tar.xz PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq -PKG_HASH:=84523646f3116bb5e1151efb66e645030f6e6a8256f29aab444777a343ebc132 +PKG_HASH:=ffc1f7e8b05e22d910b9a71d09f1128197292766dc7c54cb7018a1b2c3af4aea PKG_LICENSE:=GPL-2.0 PKG_LICENSE_FILES:=COPYING diff --git a/package/network/services/dnsmasq/patches/100-remove-old-runtime-kernel-support.patch b/package/network/services/dnsmasq/patches/100-remove-old-runtime-kernel-support.patch index aaa5a76909..bd11806ae0 100644 --- a/package/network/services/dnsmasq/patches/100-remove-old-runtime-kernel-support.patch +++ b/package/network/services/dnsmasq/patches/100-remove-old-runtime-kernel-support.patch @@ -27,7 +27,7 @@ Signed-off-by: Kevin Darbyshire-Bryant --- a/src/dnsmasq.h +++ b/src/dnsmasq.h -@@ -1112,7 +1112,7 @@ extern struct daemon { +@@ -1125,7 +1125,7 @@ extern struct daemon { int inotifyfd; #endif #if defined(HAVE_LINUX_NETWORK) @@ -36,7 +36,7 @@ Signed-off-by: Kevin Darbyshire-Bryant #elif defined(HAVE_BSD_NETWORK) int dhcp_raw_fd, dhcp_icmp_fd, routefd; #endif -@@ -1292,9 +1292,6 @@ int read_write(int fd, unsigned char *pa +@@ -1306,9 +1306,6 @@ int read_write(int fd, unsigned char *pa void close_fds(long max_fd, int spare1, int spare2, int spare3); int wildcard_match(const char* wildcard, const char* match); int wildcard_matchn(const char* wildcard, const char* match, int num); From 38bdff29aa132a049228cbfc1d87064ceb6f824b Mon Sep 17 00:00:00 2001 From: John Audia Date: Sun, 17 Jan 2021 09:15:14 -0500 Subject: [PATCH 22/34] kernel: bump 5.4 to 5.4.90 All modification made by update_kernel.sh in a fresh clone without existing toolchains. Build system: x86_64 Build-tested: ipq806x/R7800, bcm27xx/bcm2711 Run-tested: ipq806x/R7800 No dmesg regressions, everything functional Signed-off-by: John Audia Tested-by: Curtis Deptuck [x86/64] --- include/kernel-version.mk | 4 ++-- target/linux/generic/hack-5.4/221-module_exports.patch | 2 +- ...net-phylink-propagate-resolved-link-config-via-mac_l.patch | 2 +- ...net-dsa-propagate-resolved-link-config-via-mac_link_.patch | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/kernel-version.mk b/include/kernel-version.mk index 8b2577961c..acd651f9ed 100644 --- a/include/kernel-version.mk +++ b/include/kernel-version.mk @@ -6,9 +6,9 @@ ifdef CONFIG_TESTING_KERNEL KERNEL_PATCHVER:=$(KERNEL_TESTING_PATCHVER) endif -LINUX_VERSION-5.4 = .89 +LINUX_VERSION-5.4 = .90 -LINUX_KERNEL_HASH-5.4.89 = 268dd5177b6df1867d4ed2452ffb11a016d955c43aba5e07940886f347ab0aaf +LINUX_KERNEL_HASH-5.4.90 = 646736bc063f181c22648934f0dc3d97d49aec6edfd7358d2fe3df29fb66fa1a remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1)))) sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1))))))) diff --git a/target/linux/generic/hack-5.4/221-module_exports.patch b/target/linux/generic/hack-5.4/221-module_exports.patch index f651cd902e..4f805cf7e3 100644 --- a/target/linux/generic/hack-5.4/221-module_exports.patch +++ b/target/linux/generic/hack-5.4/221-module_exports.patch @@ -56,7 +56,7 @@ Signed-off-by: Felix Fietkau } \ \ /* __*init sections */ \ -@@ -885,6 +895,8 @@ +@@ -888,6 +898,8 @@ EXIT_TEXT \ EXIT_DATA \ EXIT_CALL \ diff --git a/target/linux/mediatek/patches-5.4/0600-net-phylink-propagate-resolved-link-config-via-mac_l.patch b/target/linux/mediatek/patches-5.4/0600-net-phylink-propagate-resolved-link-config-via-mac_l.patch index 0c9ef86a3b..fc987e8e9d 100644 --- a/target/linux/mediatek/patches-5.4/0600-net-phylink-propagate-resolved-link-config-via-mac_l.patch +++ b/target/linux/mediatek/patches-5.4/0600-net-phylink-propagate-resolved-link-config-via-mac_l.patch @@ -95,7 +95,7 @@ Signed-off-by: David S. Miller } netif_tx_start_all_queues(port->dev); -@@ -5127,8 +5131,11 @@ static void mvpp2_mac_config(struct phyl +@@ -5139,8 +5143,11 @@ static void mvpp2_mac_config(struct phyl mvpp2_port_enable(port); } diff --git a/target/linux/mediatek/patches-5.4/0601-net-dsa-propagate-resolved-link-config-via-mac_link_.patch b/target/linux/mediatek/patches-5.4/0601-net-dsa-propagate-resolved-link-config-via-mac_link_.patch index ef6f66e3fc..7a34dbad6e 100644 --- a/target/linux/mediatek/patches-5.4/0601-net-dsa-propagate-resolved-link-config-via-mac_link_.patch +++ b/target/linux/mediatek/patches-5.4/0601-net-dsa-propagate-resolved-link-config-via-mac_link_.patch @@ -51,7 +51,7 @@ Signed-off-by: David S. Miller struct ethtool_eee *p = &priv->dev->ports[port].eee; --- a/drivers/net/dsa/lantiq_gswip.c +++ b/drivers/net/dsa/lantiq_gswip.c -@@ -1507,7 +1507,9 @@ static void gswip_phylink_mac_link_down( +@@ -1508,7 +1508,9 @@ static void gswip_phylink_mac_link_down( static void gswip_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode, phy_interface_t interface, From 0fda8049a7d1fb34074b7d5e8041312c1971f87d Mon Sep 17 00:00:00 2001 From: Nick Hainke Date: Sat, 16 Jan 2021 13:48:50 +0100 Subject: [PATCH 23/34] owipcalc: remove clone in cidr_contains6 The "cidr_contains6" functions clones the given cidr. The contains4 does not clone the cidr. Both functions do not behave the same. I see no reason to push the cidr. I think that we get only a negligible performance gain, but it makes ipv4 and ipv6 equal again. Signed-off-by: Nick Hainke --- package/network/utils/owipcalc/Makefile | 2 +- package/network/utils/owipcalc/src/owipcalc.c | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/package/network/utils/owipcalc/Makefile b/package/network/utils/owipcalc/Makefile index 1f4c98bb48..dc68a0346b 100644 --- a/package/network/utils/owipcalc/Makefile +++ b/package/network/utils/owipcalc/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=owipcalc -PKG_RELEASE:=4 +PKG_RELEASE:=5 PKG_LICENSE:=Apache-2.0 include $(INCLUDE_DIR)/package.mk diff --git a/package/network/utils/owipcalc/src/owipcalc.c b/package/network/utils/owipcalc/src/owipcalc.c index c4df5c7450..5ed609f158 100644 --- a/package/network/utils/owipcalc/src/owipcalc.c +++ b/package/network/utils/owipcalc/src/owipcalc.c @@ -527,18 +527,17 @@ static bool cidr_network6(struct cidr *a) static bool cidr_contains6(struct cidr *a, struct cidr *b) { - struct cidr *n = cidr_clone(a); - struct in6_addr *x = &n->addr.v6; + struct in6_addr *x = &a->addr.v6; struct in6_addr *y = &b->addr.v6; - uint8_t i = (128 - n->prefix) / 8; - uint8_t m = ~((1 << ((128 - n->prefix) % 8)) - 1); + uint8_t i = (128 - a->prefix) / 8; + uint8_t m = ~((1 << ((128 - a->prefix) % 8)) - 1); uint8_t net1 = x->s6_addr[15-i] & m; uint8_t net2 = y->s6_addr[15-i] & m; if (printed) qprintf(" "); - if ((b->prefix >= n->prefix) && (net1 == net2) && + if ((b->prefix >= a->prefix) && (net1 == net2) && ((i == 15) || !memcmp(&x->s6_addr, &y->s6_addr, 15-i))) { qprintf("1"); From 4b35999588ee6dbe1fd818760b358b1191ddd0be Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 23 Nov 2020 13:41:34 +0100 Subject: [PATCH 24/34] ath79: Add support for OpenMesh MR600 v1 Device specifications: ====================== * Qualcomm/Atheros AR9344 rev 2 * 560/450/225 MHz (CPU/DDR/AHB) * 128 MB of RAM * 16 MB of SPI NOR flash - 2x 7 MB available; but one of the 7 MB regions is the recovery image * 2T2R 2.4 GHz Wi-Fi * 2T2R 5 GHz Wi-Fi * 4x GPIO-LEDs (2x wifi, 1x wps, 1x power) * 1x GPIO-button (reset) * TTL pins are on board (arrow points to VCC, then follows: GND, TX, RX) * 1x ethernet - AR8035 ethernet PHY (RGMII) - 10/100/1000 Mbps Ethernet - 802.3af POE - used as LAN interface * 12-24V 1A DC * internal antennas Flashing instructions: ====================== Various methods can be used to install the actual image on the flash. Two easy ones are: ap51-flash ---------- The tool ap51-flash (https://github.com/ap51-flash/ap51-flash) should be used to transfer the image to the u-boot when the device boots up. initramfs from TFTP ------------------- The serial console must be used to access the u-boot shell during bootup. It can then be used to first boot up the initramfs image from a TFTP server (here with the IP 192.168.1.21): setenv serverip 192.168.1.21 setenv ipaddr 192.168.1.1 tftpboot 0c00000 .bin && bootm $fileaddr The actual sysupgrade image can then be transferred (on the LAN port) to the device via scp .bin root@192.168.1.1:/tmp/ On the device, the sysupgrade must then be started using sysupgrade -n /tmp/.bin Signed-off-by: Sven Eckelmann [rebase, make WLAN LEDs consistent, add LED migration] Signed-off-by: Adrian Schmutzler --- package/boot/uboot-envtools/files/ath79 | 1 + .../ath79/dts/ar9344_openmesh_mr600-v1.dts | 46 ++++++ .../ath79/dts/ar9344_openmesh_mr600.dtsi | 133 ++++++++++++++++++ .../generic/base-files/etc/board.d/02_network | 1 + .../etc/hotplug.d/firmware/10-ath9k-eeprom | 3 + .../etc/uci-defaults/04_led_migration | 3 + .../base-files/lib/upgrade/platform.sh | 1 + target/linux/ath79/image/generic.mk | 20 +++ 8 files changed, 208 insertions(+) create mode 100644 target/linux/ath79/dts/ar9344_openmesh_mr600-v1.dts create mode 100644 target/linux/ath79/dts/ar9344_openmesh_mr600.dtsi diff --git a/package/boot/uboot-envtools/files/ath79 b/package/boot/uboot-envtools/files/ath79 index dedf7160f0..3cdb71a69e 100644 --- a/package/boot/uboot-envtools/files/ath79 +++ b/package/boot/uboot-envtools/files/ath79 @@ -48,6 +48,7 @@ netgear,wnr2200-16m|\ netgear,wnr612-v2|\ ocedo,koala|\ ocedo,raccoon|\ +openmesh,mr600-v1|\ openmesh,om5p|\ openmesh,om5p-ac-v2|\ samsung,wam250|\ diff --git a/target/linux/ath79/dts/ar9344_openmesh_mr600-v1.dts b/target/linux/ath79/dts/ar9344_openmesh_mr600-v1.dts new file mode 100644 index 0000000000..6c20f2715f --- /dev/null +++ b/target/linux/ath79/dts/ar9344_openmesh_mr600-v1.dts @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "ar9344_openmesh_mr600.dtsi" + +/ { + compatible = "openmesh,mr600-v1", "qca,ar9344"; + model = "OpenMesh MR600 v1"; + + aliases { + led-boot = &led_power_orange; + led-failsafe = &led_power_orange; + led-running = &led_power_orange; + led-upgrade = &led_power_orange; + }; + + leds { + compatible = "gpio-leds"; + + wifi5g_green { + label = "green:wifi5g"; + gpios = <&gpio 12 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy0tpt"; + }; + + wps_blue { + label = "blue:wps"; + gpios = <&gpio 13 GPIO_ACTIVE_LOW>; + }; + + led_power_orange: power_orange { + label = "orange:power"; + gpios = <&gpio 14 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + }; + + leds-ath9k { + compatible = "gpio-leds"; + + wifi2g { + label = "blue:wifi2g"; + gpios = <&ath9k 0 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy1tpt"; + }; + }; +}; diff --git a/target/linux/ath79/dts/ar9344_openmesh_mr600.dtsi b/target/linux/ath79/dts/ar9344_openmesh_mr600.dtsi new file mode 100644 index 0000000000..987a32e344 --- /dev/null +++ b/target/linux/ath79/dts/ar9344_openmesh_mr600.dtsi @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "ar9344.dtsi" + +#include +#include + +/ { + chosen { + /delete-property/ bootargs; + }; + + aliases { + serial0 = &uart; + label-mac-device = ð0; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + linux,code = ; + gpios = <&gpio 17 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&ref { + clock-frequency = <40000000>; +}; + +&uart { + status = "okay"; +}; + +&spi { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>; + + /* partitions are passed via bootloader */ + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x000000 0x040000>; + read-only; + }; + + partition@40000 { + label = "u-boot-env"; + reg = <0x040000 0x010000>; + }; + + partition@50000 { + label = "custom"; + reg = <0x050000 0x060000>; + read-only; + }; + + partition@b0000 { + label = "inactive"; + reg = <0x0b0000 0x7a0000>; + }; + + partition@850000 { + label = "inactive2"; + reg = <0x850000 0x7a0000>; + }; + + art: partition@ff0000 { + label = "ART"; + reg = <0xff0000 0x010000>; + read-only; + }; + }; + }; +}; + +&mdio0 { + status = "okay"; + + phy-mask = <0x1>; + + phy0: ethernet-phy@0 { + reg = <0>; + eee-broken-100tx; + eee-broken-1000t; + }; +}; + +ð0 { + status = "okay"; + + pll-data = <0x06000000 0x00000101 0x00001313>; + + mtd-mac-address = <&art 0x0>; + + phy-mode = "rgmii"; + phy-handle = <&phy0>; + + gmac-config { + device = <&gmac>; + rgmii-gmac0 = <1>; + }; +}; + +&wmac { + status = "okay"; + + mtd-cal-data = <&art 0x1000>; + mtd-mac-address = <&art 0x0>; + mtd-mac-address-increment = <1>; +}; + +&pcie { + status = "okay"; + + ath9k: wifi@0,0 { + compatible = "pci168c,0030"; + reg = <0x0000 0 0 0 0>; + qca,no-eeprom; + mtd-mac-address = <&art 0x0>; + mtd-mac-address-increment = <8>; + }; +}; diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network index fbe2545adb..df0842fc63 100755 --- a/target/linux/ath79/generic/base-files/etc/board.d/02_network +++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network @@ -46,6 +46,7 @@ ath79_setup_interfaces() netgear,ex7300|\ ocedo,koala|\ ocedo,raccoon|\ + openmesh,mr600-v1|\ pcs,cap324|\ pisen,ts-d084|\ pisen,wmb001n|\ diff --git a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom index 95ad2a57ef..150c70d68b 100644 --- a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom +++ b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom @@ -120,6 +120,9 @@ case "$FIRMWARE" in ubnt,rocket-m) caldata_extract "art" 0x1000 0x1000 ;; + openmesh,mr600-v1) + caldata_extract "ART" 0x5000 0x440 + ;; wd,mynet-n750) caldata_extract "art" 0x5000 0x440 ath9k_patch_mac $(mtd_get_mac_ascii devdata "wlan5mac") diff --git a/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration b/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration index 231afd9f57..871d84ed63 100644 --- a/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration +++ b/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration @@ -17,6 +17,9 @@ engenius,epg5000) glinet,gl-mifi) migrate_leds ":net=:3g4g" ;; +openmesh,mr600-v1) + migrate_leds ":wlan58=:wifi5g" + ;; pcs,cap324) migrate_leds "lan:amber=amber:lan" "lan:green=green:lan" ;; diff --git a/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh b/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh index 79e023482b..81dd911564 100644 --- a/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh +++ b/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh @@ -50,6 +50,7 @@ platform_do_upgrade() { jjplus,ja76pf2) redboot_fis_do_upgrade "$1" linux ;; + openmesh,mr600-v1|\ openmesh,om2p-v2|\ openmesh,om2p-v4|\ openmesh,om2p-hs-v1|\ diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk index ccc9ff2ac2..14546f6ade 100644 --- a/target/linux/ath79/image/generic.mk +++ b/target/linux/ath79/image/generic.mk @@ -1525,6 +1525,26 @@ define Device/ocedo_ursus endef TARGET_DEVICES += ocedo_ursus +define Device/openmesh_mr600-common + SOC := ar9344 + DEVICE_VENDOR := OpenMesh + DEVICE_MODEL := MR600 + DEVICE_PACKAGES := uboot-envtools + IMAGE_SIZE := 7808k + BLOCKSIZE := 64k + KERNEL := kernel-bin | append-dtb | lzma | uImage lzma | \ + pad-to $$(BLOCKSIZE) + IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | \ + openmesh-image ce_type=MR600 | append-metadata +endef + +define Device/openmesh_mr600-v1 + $(Device/openmesh_mr600-common) + DEVICE_VARIANT := v1 + SUPPORTED_DEVICES += mr600 +endef +TARGET_DEVICES += openmesh_mr600-v1 + define Device/openmesh_om2p-common DEVICE_VENDOR := OpenMesh DEVICE_PACKAGES := uboot-envtools From d9a3af46d8a1001223c2a327f449b7048d0fd5f6 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 23 Nov 2020 13:41:34 +0100 Subject: [PATCH 25/34] ath79: Add support for OpenMesh MR600 v2 Device specifications: ====================== * Qualcomm/Atheros AR9344 rev 2 * 560/450/225 MHz (CPU/DDR/AHB) * 128 MB of RAM * 16 MB of SPI NOR flash - 2x 7 MB available; but one of the 7 MB regions is the recovery image * 2T2R 2.4 GHz Wi-Fi * 2T2R 5 GHz Wi-Fi * 8x GPIO-LEDs (6x wifi, 1x wps, 1x power) * 1x GPIO-button (reset) * external h/w watchdog (enabled by default)) * TTL pins are on board (arrow points to VCC, then follows: GND, TX, RX) * 1x ethernet - AR8035 ethernet PHY (RGMII) - 10/100/1000 Mbps Ethernet - 802.3af POE - used as LAN interface * 12-24V 1A DC * internal antennas Flashing instructions: ====================== Various methods can be used to install the actual image on the flash. Two easy ones are: ap51-flash ---------- The tool ap51-flash (https://github.com/ap51-flash/ap51-flash) should be used to transfer the image to the u-boot when the device boots up. initramfs from TFTP ------------------- The serial console must be used to access the u-boot shell during bootup. It can then be used to first boot up the initramfs image from a TFTP server (here with the IP 192.168.1.21): setenv serverip 192.168.1.21 setenv ipaddr 192.168.1.1 tftpboot 0c00000 .bin && bootm $fileaddr The actual sysupgrade image can then be transferred (on the LAN port) to the device via scp .bin root@192.168.1.1:/tmp/ On the device, the sysupgrade must then be started using sysupgrade -n /tmp/.bin Signed-off-by: Sven Eckelmann [rebase, add LED migration] Signed-off-by: Adrian Schmutzler --- package/boot/uboot-envtools/Makefile | 2 +- package/boot/uboot-envtools/files/ath79 | 1 + .../ath79/dts/ar9344_openmesh_mr600-v2.dts | 71 +++++++++++++++++++ .../generic/base-files/etc/board.d/02_network | 1 + .../etc/hotplug.d/firmware/10-ath9k-eeprom | 3 +- .../etc/uci-defaults/04_led_migration | 3 + .../base-files/lib/upgrade/platform.sh | 1 + target/linux/ath79/image/generic.mk | 7 ++ 8 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 target/linux/ath79/dts/ar9344_openmesh_mr600-v2.dts diff --git a/package/boot/uboot-envtools/Makefile b/package/boot/uboot-envtools/Makefile index 8bc2c00ba5..4847653f3f 100644 --- a/package/boot/uboot-envtools/Makefile +++ b/package/boot/uboot-envtools/Makefile @@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=uboot-envtools PKG_DISTNAME:=u-boot PKG_VERSION:=2020.04 -PKG_RELEASE:=17 +PKG_RELEASE:=18 PKG_SOURCE:=$(PKG_DISTNAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:= \ diff --git a/package/boot/uboot-envtools/files/ath79 b/package/boot/uboot-envtools/files/ath79 index 3cdb71a69e..028b00ac43 100644 --- a/package/boot/uboot-envtools/files/ath79 +++ b/package/boot/uboot-envtools/files/ath79 @@ -49,6 +49,7 @@ netgear,wnr612-v2|\ ocedo,koala|\ ocedo,raccoon|\ openmesh,mr600-v1|\ +openmesh,mr600-v2|\ openmesh,om5p|\ openmesh,om5p-ac-v2|\ samsung,wam250|\ diff --git a/target/linux/ath79/dts/ar9344_openmesh_mr600-v2.dts b/target/linux/ath79/dts/ar9344_openmesh_mr600-v2.dts new file mode 100644 index 0000000000..988066798f --- /dev/null +++ b/target/linux/ath79/dts/ar9344_openmesh_mr600-v2.dts @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "ar9344_openmesh_mr600.dtsi" + +/ { + compatible = "openmesh,mr600-v2", "qca,ar9344"; + model = "OpenMesh MR600 v2"; + + aliases { + led-boot = &led_power_blue; + led-failsafe = &led_power_blue; + led-running = &led_power_blue; + led-upgrade = &led_power_blue; + }; + + leds { + compatible = "gpio-leds"; + + wifi5g_red { + label = "red:wifi5g"; + gpios = <&gpio 12 GPIO_ACTIVE_LOW>; + }; + + wps_blue { + label = "blue:wps"; + gpios = <&gpio 13 GPIO_ACTIVE_LOW>; + }; + + led_power_blue: power_blue { + label = "blue:power"; + gpios = <&gpio 14 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + + wifi2g_green { + label = "green:wifi2g"; + gpios = <&gpio 18 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy1tpt"; + }; + + wifi2g_yellow { + label = "yellow:wifi2g"; + gpios = <&gpio 19 GPIO_ACTIVE_LOW>; + }; + + wifi2g_red { + label = "red:wifi2g"; + gpios = <&gpio 20 GPIO_ACTIVE_LOW>; + }; + + wifi5g_green { + label = "green:wifi5g"; + gpios = <&gpio 21 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy0tpt"; + }; + + wifi5g_yellow { + label = "yellow:wifi5g"; + gpios = <&gpio 22 GPIO_ACTIVE_LOW>; + }; + }; + + watchdog { + compatible = "linux,wdt-gpio"; + gpios = <&gpio 15 GPIO_ACTIVE_LOW>; + hw_algo = "toggle"; + /* hw_margin_ms is actually 300s but driver limits it to 60s */ + hw_margin_ms = <60000>; + always-running; + }; +}; diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network index df0842fc63..3c37781c0e 100755 --- a/target/linux/ath79/generic/base-files/etc/board.d/02_network +++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network @@ -47,6 +47,7 @@ ath79_setup_interfaces() ocedo,koala|\ ocedo,raccoon|\ openmesh,mr600-v1|\ + openmesh,mr600-v2|\ pcs,cap324|\ pisen,ts-d084|\ pisen,wmb001n|\ diff --git a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom index 150c70d68b..d50d8d9f82 100644 --- a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom +++ b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom @@ -120,7 +120,8 @@ case "$FIRMWARE" in ubnt,rocket-m) caldata_extract "art" 0x1000 0x1000 ;; - openmesh,mr600-v1) + openmesh,mr600-v1|\ + openmesh,mr600-v2) caldata_extract "ART" 0x5000 0x440 ;; wd,mynet-n750) diff --git a/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration b/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration index 871d84ed63..88c4f527b7 100644 --- a/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration +++ b/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration @@ -20,6 +20,9 @@ glinet,gl-mifi) openmesh,mr600-v1) migrate_leds ":wlan58=:wifi5g" ;; +openmesh,mr600-v2) + migrate_leds ":wlan24=:wifi2g" ":wlan58=:wifi5g" + ;; pcs,cap324) migrate_leds "lan:amber=amber:lan" "lan:green=green:lan" ;; diff --git a/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh b/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh index 81dd911564..e14adb38fa 100644 --- a/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh +++ b/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh @@ -51,6 +51,7 @@ platform_do_upgrade() { redboot_fis_do_upgrade "$1" linux ;; openmesh,mr600-v1|\ + openmesh,mr600-v2|\ openmesh,om2p-v2|\ openmesh,om2p-v4|\ openmesh,om2p-hs-v1|\ diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk index 14546f6ade..9a182cab79 100644 --- a/target/linux/ath79/image/generic.mk +++ b/target/linux/ath79/image/generic.mk @@ -1545,6 +1545,13 @@ define Device/openmesh_mr600-v1 endef TARGET_DEVICES += openmesh_mr600-v1 +define Device/openmesh_mr600-v2 + $(Device/openmesh_mr600-common) + DEVICE_VARIANT := v2 + SUPPORTED_DEVICES += mr600v2 +endef +TARGET_DEVICES += openmesh_mr600-v2 + define Device/openmesh_om2p-common DEVICE_VENDOR := OpenMesh DEVICE_PACKAGES := uboot-envtools From 7b772e07ea0cf637994a2c5631c1f28756c6b5a3 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Wed, 30 Dec 2020 21:56:55 +0100 Subject: [PATCH 26/34] ath79: apply Engenius EAP600 style to OpenMesh MR600 RGMII cfg The OpenMesh MR600 is a modified version of the EAP600 family. These devices are shipped with an AR803x PHY and had various problems with the delay configuration in ar71xx. These problems are now in the past [1] and parts of the delay configuration should now be done in the PHY only. Just switch to the configuration of the EAP600 to have an already well tested configuration for ath79 with the newer kernel versions. [1] https://github.com/openwrt/openwrt/pull/3505#issuecomment-716050292 Reported-by: Michael Pratt Signed-off-by: Sven Eckelmann --- target/linux/ath79/dts/ar9344_openmesh_mr600.dtsi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/target/linux/ath79/dts/ar9344_openmesh_mr600.dtsi b/target/linux/ath79/dts/ar9344_openmesh_mr600.dtsi index 987a32e344..8517576787 100644 --- a/target/linux/ath79/dts/ar9344_openmesh_mr600.dtsi +++ b/target/linux/ath79/dts/ar9344_openmesh_mr600.dtsi @@ -99,16 +99,18 @@ ð0 { status = "okay"; - pll-data = <0x06000000 0x00000101 0x00001313>; + pll-data = <0x02000000 0x00000101 0x00001313>; mtd-mac-address = <&art 0x0>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-handle = <&phy0>; gmac-config { device = <&gmac>; rgmii-gmac0 = <1>; + rxdv-delay = <3>; + rxd-delay = <3>; }; }; From e06c9eec5dc8a3721df768ab952712cf015d4e6f Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 23 Nov 2020 13:41:34 +0100 Subject: [PATCH 27/34] ath79: Add support for OpenMesh MR900 v1 Device specifications: ====================== * Qualcomm/Atheros QCA9558 ver 1 rev 0 * 720/600/240 MHz (CPU/DDR/AHB) * 128 MB of RAM * 16 MB of SPI NOR flash - 2x 7 MB available; but one of the 7 MB regions is the recovery image * 3T3R 2.4 GHz Wi-Fi * 3T3R 5 GHz Wi-Fi * 6x GPIO-LEDs (2x wifi, 2x status, 1x lan, 1x power) * 1x GPIO-button (reset) * external h/w watchdog (enabled by default)) * TTL pins are on board (arrow points to VCC, then follows: GND, TX, RX) * 1x ethernet - AR8035 ethernet PHY (RGMII) - 10/100/1000 Mbps Ethernet - 802.3af POE - used as LAN interface * 12-24V 1A DC * internal antennas Flashing instructions: ====================== Various methods can be used to install the actual image on the flash. Two easy ones are: ap51-flash ---------- The tool ap51-flash (https://github.com/ap51-flash/ap51-flash) should be used to transfer the image to the u-boot when the device boots up. initramfs from TFTP ------------------- The serial console must be used to access the u-boot shell during bootup. It can then be used to first boot up the initramfs image from a TFTP server (here with the IP 192.168.1.21): setenv serverip 192.168.1.21 setenv ipaddr 192.168.1.1 tftpboot 0c00000 .bin && bootm $fileaddr The actual sysupgrade image can then be transferred (on the LAN port) to the device via scp .bin root@192.168.1.1:/tmp/ On the device, the sysupgrade must then be started using sysupgrade -n /tmp/.bin Signed-off-by: Sven Eckelmann [rebase, add LED migration] Signed-off-by: Adrian Schmutzler --- package/boot/uboot-envtools/files/ath79 | 1 + .../ath79/dts/qca9558_openmesh_mr900-v1.dts | 8 + .../ath79/dts/qca9558_openmesh_mr900.dtsi | 182 ++++++++++++++++++ .../generic/base-files/etc/board.d/01_leds | 3 +- .../generic/base-files/etc/board.d/02_network | 1 + .../etc/uci-defaults/04_led_migration | 3 + .../base-files/lib/upgrade/platform.sh | 1 + target/linux/ath79/image/generic.mk | 20 ++ 8 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 target/linux/ath79/dts/qca9558_openmesh_mr900-v1.dts create mode 100644 target/linux/ath79/dts/qca9558_openmesh_mr900.dtsi diff --git a/package/boot/uboot-envtools/files/ath79 b/package/boot/uboot-envtools/files/ath79 index 028b00ac43..816d3b1a88 100644 --- a/package/boot/uboot-envtools/files/ath79 +++ b/package/boot/uboot-envtools/files/ath79 @@ -50,6 +50,7 @@ ocedo,koala|\ ocedo,raccoon|\ openmesh,mr600-v1|\ openmesh,mr600-v2|\ +openmesh,mr900-v1|\ openmesh,om5p|\ openmesh,om5p-ac-v2|\ samsung,wam250|\ diff --git a/target/linux/ath79/dts/qca9558_openmesh_mr900-v1.dts b/target/linux/ath79/dts/qca9558_openmesh_mr900-v1.dts new file mode 100644 index 0000000000..96fc9853cb --- /dev/null +++ b/target/linux/ath79/dts/qca9558_openmesh_mr900-v1.dts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca9558_openmesh_mr900.dtsi" + +/ { + compatible = "openmesh,mr900-v1", "qca,qca9558"; + model = "OpenMesh MR900 v1"; +}; diff --git a/target/linux/ath79/dts/qca9558_openmesh_mr900.dtsi b/target/linux/ath79/dts/qca9558_openmesh_mr900.dtsi new file mode 100644 index 0000000000..e506e12c31 --- /dev/null +++ b/target/linux/ath79/dts/qca9558_openmesh_mr900.dtsi @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca955x.dtsi" + +#include +#include + +/ { + chosen { + /delete-property/ bootargs; + }; + + aliases { + serial0 = &uart; + led-boot = &led_power_blue; + led-failsafe = &led_power_blue; + led-running = &led_power_blue; + led-upgrade = &led_power_blue; + label-mac-device = ð0; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + linux,code = ; + gpios = <&gpio 17 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + + lan_blue { + label = "blue:lan"; + gpios = <&gpio 12 GPIO_ACTIVE_LOW>; + }; + + wifi2g_blue { + label = "blue:wifi2g"; + gpios = <&gpio 13 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy0tpt"; + }; + + status_green { + label = "green:status"; + gpios = <&gpio 19 GPIO_ACTIVE_LOW>; + }; + + status_red { + label = "red:status"; + gpios = <&gpio 21 GPIO_ACTIVE_LOW>; + }; + + led_power_blue: power_blue { + label = "blue:power"; + gpios = <&gpio 22 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + + wifi5g_blue { + label = "blue:wifi5g"; + gpios = <&gpio 23 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy1tpt"; + }; + }; + + watchdog { + compatible = "linux,wdt-gpio"; + gpios = <&gpio 16 GPIO_ACTIVE_LOW>; + hw_algo = "toggle"; + /* hw_margin_ms is actually 300s but driver limits it to 60s */ + hw_margin_ms = <60000>; + always-running; + }; +}; + +&uart { + status = "okay"; +}; + +&spi { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>; + + /* partitions are passed via bootloader */ + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x000000 0x040000>; + read-only; + }; + + partition@40000 { + label = "u-boot-env"; + reg = <0x040000 0x010000>; + }; + + partition@50000 { + label = "custom"; + reg = <0x050000 0x060000>; + read-only; + }; + + partition@b0000 { + label = "inactive"; + reg = <0x0b0000 0x7a0000>; + }; + + partition@850000 { + label = "inactive2"; + reg = <0x850000 0x7a0000>; + }; + + art: partition@ff0000 { + label = "ART"; + reg = <0xff0000 0x010000>; + read-only; + }; + }; + }; +}; + +&mdio0 { + status = "okay"; + + phy-mask = <0x20>; + + phy5: ethernet-phy@5 { + reg = <5>; + eee-broken-100tx; + eee-broken-1000t; + }; +}; + +ð0 { + status = "okay"; + + pll-data = <0xae000000 0xa0000101 0xa0001313>; + + mtd-mac-address = <&art 0x0>; + + phy-mode = "rgmii-rxid"; + phy-handle = <&phy5>; + + gmac-config { + device = <&gmac>; + rgmii-enabled = <1>; + rxd-delay = <3>; + rxdv-delay = <3>; + txd-delay = <0>; + txen-delay = <0>; + }; +}; + +&wmac { + status = "okay"; + + mtd-cal-data = <&art 0x1000>; + mtd-mac-address = <&art 0x0>; + mtd-mac-address-increment = <1>; +}; + +&pcie0 { + status = "okay"; + + wifi@0,0 { + compatible = "pci168c,0033"; + reg = <0x0000 0 0 0 0>; + mtd-mac-address = <&art 0x0>; + mtd-mac-address-increment = <16>; + }; +}; diff --git a/target/linux/ath79/generic/base-files/etc/board.d/01_leds b/target/linux/ath79/generic/base-files/etc/board.d/01_leds index 9e5e42e268..034c2d2933 100755 --- a/target/linux/ath79/generic/base-files/etc/board.d/01_leds +++ b/target/linux/ath79/generic/base-files/etc/board.d/01_leds @@ -157,7 +157,8 @@ telco,t1) ;; comfast,cf-wr752ac-v1|\ engenius,eap300-v2|\ -enterasys,ws-ap3705i) +enterasys,ws-ap3705i|\ +openmesh,mr900-v1) ucidef_set_led_netdev "lan" "LAN" "blue:lan" "eth0" ;; compex,wpj344-16m|\ diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network index 3c37781c0e..8a15d2ad55 100755 --- a/target/linux/ath79/generic/base-files/etc/board.d/02_network +++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network @@ -48,6 +48,7 @@ ath79_setup_interfaces() ocedo,raccoon|\ openmesh,mr600-v1|\ openmesh,mr600-v2|\ + openmesh,mr900-v1|\ pcs,cap324|\ pisen,ts-d084|\ pisen,wmb001n|\ diff --git a/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration b/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration index 88c4f527b7..ad14eb2941 100644 --- a/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration +++ b/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration @@ -23,6 +23,9 @@ openmesh,mr600-v1) openmesh,mr600-v2) migrate_leds ":wlan24=:wifi2g" ":wlan58=:wifi5g" ;; +openmesh,mr900-v1) + migrate_leds ":wlan24=:wifi2g" ":wlan58=:wifi5g" ":wan=:lan" + ;; pcs,cap324) migrate_leds "lan:amber=amber:lan" "lan:green=green:lan" ;; diff --git a/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh b/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh index e14adb38fa..40197cfaa8 100644 --- a/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh +++ b/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh @@ -52,6 +52,7 @@ platform_do_upgrade() { ;; openmesh,mr600-v1|\ openmesh,mr600-v2|\ + openmesh,mr900-v1|\ openmesh,om2p-v2|\ openmesh,om2p-v4|\ openmesh,om2p-hs-v1|\ diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk index 9a182cab79..9d6fd398d9 100644 --- a/target/linux/ath79/image/generic.mk +++ b/target/linux/ath79/image/generic.mk @@ -1552,6 +1552,26 @@ define Device/openmesh_mr600-v2 endef TARGET_DEVICES += openmesh_mr600-v2 +define Device/openmesh_mr900-common + SOC := qca9558 + DEVICE_VENDOR := OpenMesh + DEVICE_MODEL := MR900 + DEVICE_PACKAGES := uboot-envtools + IMAGE_SIZE := 7808k + BLOCKSIZE := 64k + KERNEL := kernel-bin | append-dtb | lzma | uImage lzma | \ + pad-to $$(BLOCKSIZE) + IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | \ + openmesh-image ce_type=MR900 | append-metadata +endef + +define Device/openmesh_mr900-v1 + $(Device/openmesh_mr900-common) + DEVICE_VARIANT := v1 + SUPPORTED_DEVICES += mr900 +endef +TARGET_DEVICES += openmesh_mr900-v1 + define Device/openmesh_om2p-common DEVICE_VENDOR := OpenMesh DEVICE_PACKAGES := uboot-envtools From 31172e53f9d0971204e6fa7e3541c0695d99618a Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 23 Nov 2020 13:41:34 +0100 Subject: [PATCH 28/34] ath79: Add support for OpenMesh MR900 v2 Device specifications: ====================== * Qualcomm/Atheros QCA9558 ver 1 rev 0 * 720/600/240 MHz (CPU/DDR/AHB) * 128 MB of RAM * 16 MB of SPI NOR flash - 2x 7 MB available; but one of the 7 MB regions is the recovery image * 3T3R 2.4 GHz Wi-Fi * 3T3R 5 GHz Wi-Fi * 6x GPIO-LEDs (2x wifi, 2x status, 1x lan, 1x power) * 1x GPIO-button (reset) * external h/w watchdog (enabled by default)) * TTL pins are on board (arrow points to VCC, then follows: GND, TX, RX) * 1x ethernet - AR8035 ethernet PHY (RGMII) - 10/100/1000 Mbps Ethernet - 802.3af POE - used as LAN interface * 12-24V 1A DC * internal antennas Flashing instructions: ====================== Various methods can be used to install the actual image on the flash. Two easy ones are: ap51-flash ---------- The tool ap51-flash (https://github.com/ap51-flash/ap51-flash) should be used to transfer the image to the u-boot when the device boots up. initramfs from TFTP ------------------- The serial console must be used to access the u-boot shell during bootup. It can then be used to first boot up the initramfs image from a TFTP server (here with the IP 192.168.1.21): setenv serverip 192.168.1.21 setenv ipaddr 192.168.1.1 tftpboot 0c00000 .bin && bootm $fileaddr The actual sysupgrade image can then be transferred (on the LAN port) to the device via scp .bin root@192.168.1.1:/tmp/ On the device, the sysupgrade must then be started using sysupgrade -n /tmp/.bin Signed-off-by: Sven Eckelmann [rebase, add LED migration] Signed-off-by: Adrian Schmutzler --- package/boot/uboot-envtools/Makefile | 2 +- package/boot/uboot-envtools/files/ath79 | 1 + target/linux/ath79/dts/qca9558_openmesh_mr900-v2.dts | 8 ++++++++ target/linux/ath79/generic/base-files/etc/board.d/01_leds | 3 ++- .../linux/ath79/generic/base-files/etc/board.d/02_network | 1 + .../generic/base-files/etc/uci-defaults/04_led_migration | 3 ++- .../ath79/generic/base-files/lib/upgrade/platform.sh | 1 + target/linux/ath79/image/generic.mk | 7 +++++++ 8 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 target/linux/ath79/dts/qca9558_openmesh_mr900-v2.dts diff --git a/package/boot/uboot-envtools/Makefile b/package/boot/uboot-envtools/Makefile index 4847653f3f..fb025c95ea 100644 --- a/package/boot/uboot-envtools/Makefile +++ b/package/boot/uboot-envtools/Makefile @@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=uboot-envtools PKG_DISTNAME:=u-boot PKG_VERSION:=2020.04 -PKG_RELEASE:=18 +PKG_RELEASE:=19 PKG_SOURCE:=$(PKG_DISTNAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:= \ diff --git a/package/boot/uboot-envtools/files/ath79 b/package/boot/uboot-envtools/files/ath79 index 816d3b1a88..15994cec38 100644 --- a/package/boot/uboot-envtools/files/ath79 +++ b/package/boot/uboot-envtools/files/ath79 @@ -51,6 +51,7 @@ ocedo,raccoon|\ openmesh,mr600-v1|\ openmesh,mr600-v2|\ openmesh,mr900-v1|\ +openmesh,mr900-v2|\ openmesh,om5p|\ openmesh,om5p-ac-v2|\ samsung,wam250|\ diff --git a/target/linux/ath79/dts/qca9558_openmesh_mr900-v2.dts b/target/linux/ath79/dts/qca9558_openmesh_mr900-v2.dts new file mode 100644 index 0000000000..008caae2ec --- /dev/null +++ b/target/linux/ath79/dts/qca9558_openmesh_mr900-v2.dts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca9558_openmesh_mr900.dtsi" + +/ { + compatible = "openmesh,mr900-v2", "qca,qca9558"; + model = "OpenMesh MR900 v2"; +}; diff --git a/target/linux/ath79/generic/base-files/etc/board.d/01_leds b/target/linux/ath79/generic/base-files/etc/board.d/01_leds index 034c2d2933..8fba9bc0e7 100755 --- a/target/linux/ath79/generic/base-files/etc/board.d/01_leds +++ b/target/linux/ath79/generic/base-files/etc/board.d/01_leds @@ -158,7 +158,8 @@ telco,t1) comfast,cf-wr752ac-v1|\ engenius,eap300-v2|\ enterasys,ws-ap3705i|\ -openmesh,mr900-v1) +openmesh,mr900-v1|\ +openmesh,mr900-v2) ucidef_set_led_netdev "lan" "LAN" "blue:lan" "eth0" ;; compex,wpj344-16m|\ diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network index 8a15d2ad55..76bbd92c21 100755 --- a/target/linux/ath79/generic/base-files/etc/board.d/02_network +++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network @@ -49,6 +49,7 @@ ath79_setup_interfaces() openmesh,mr600-v1|\ openmesh,mr600-v2|\ openmesh,mr900-v1|\ + openmesh,mr900-v2|\ pcs,cap324|\ pisen,ts-d084|\ pisen,wmb001n|\ diff --git a/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration b/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration index ad14eb2941..453bf3b911 100644 --- a/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration +++ b/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration @@ -23,7 +23,8 @@ openmesh,mr600-v1) openmesh,mr600-v2) migrate_leds ":wlan24=:wifi2g" ":wlan58=:wifi5g" ;; -openmesh,mr900-v1) +openmesh,mr900-v1|\ +openmesh,mr900-v2) migrate_leds ":wlan24=:wifi2g" ":wlan58=:wifi5g" ":wan=:lan" ;; pcs,cap324) diff --git a/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh b/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh index 40197cfaa8..76512758b6 100644 --- a/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh +++ b/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh @@ -53,6 +53,7 @@ platform_do_upgrade() { openmesh,mr600-v1|\ openmesh,mr600-v2|\ openmesh,mr900-v1|\ + openmesh,mr900-v2|\ openmesh,om2p-v2|\ openmesh,om2p-v4|\ openmesh,om2p-hs-v1|\ diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk index 9d6fd398d9..fec7f06215 100644 --- a/target/linux/ath79/image/generic.mk +++ b/target/linux/ath79/image/generic.mk @@ -1572,6 +1572,13 @@ define Device/openmesh_mr900-v1 endef TARGET_DEVICES += openmesh_mr900-v1 +define Device/openmesh_mr900-v2 + $(Device/openmesh_mr900-common) + DEVICE_VARIANT := v2 + SUPPORTED_DEVICES += mr900v2 +endef +TARGET_DEVICES += openmesh_mr900-v2 + define Device/openmesh_om2p-common DEVICE_VENDOR := OpenMesh DEVICE_PACKAGES := uboot-envtools From 4fbdadc0bf01196d4e385872cfa805060fb127a6 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Wed, 30 Dec 2020 21:56:55 +0100 Subject: [PATCH 29/34] ath79: apply Engenius ECB1750 style to OpenMesh MR900 RGMII cfg The OpenMesh MR900 is a modified version of the Exx900/Exx1750 family. These devices are shipped with an AR803x PHY and had various problems with the delay configuration in ar71xx. These problems are now in the past [1] and parts of the delay configuration should now be done in the PHY only. Just switch to the configuration of the ECB1750 to have an already well tested configuration for ath79 with the newer kernel versions. [1] https://github.com/openwrt/openwrt/pull/3505#issuecomment-716050292 Reported-by: Michael Pratt Signed-off-by: Sven Eckelmann --- target/linux/ath79/dts/qca9558_openmesh_mr900.dtsi | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/target/linux/ath79/dts/qca9558_openmesh_mr900.dtsi b/target/linux/ath79/dts/qca9558_openmesh_mr900.dtsi index e506e12c31..8c612042c8 100644 --- a/target/linux/ath79/dts/qca9558_openmesh_mr900.dtsi +++ b/target/linux/ath79/dts/qca9558_openmesh_mr900.dtsi @@ -145,20 +145,16 @@ ð0 { status = "okay"; - pll-data = <0xae000000 0xa0000101 0xa0001313>; + pll-data = <0x82000000 0x80000101 0x80001313>; mtd-mac-address = <&art 0x0>; - phy-mode = "rgmii-rxid"; + phy-mode = "rgmii-id"; phy-handle = <&phy5>; gmac-config { device = <&gmac>; rgmii-enabled = <1>; - rxd-delay = <3>; - rxdv-delay = <3>; - txd-delay = <0>; - txen-delay = <0>; }; }; From bcb311497d3749b0a0d25c65ebad33bfa558d7eb Mon Sep 17 00:00:00 2001 From: Adrian Schmutzler Date: Tue, 19 Jan 2021 14:28:05 +0100 Subject: [PATCH 30/34] ath79: consolidate common definitions for OpenMesh devices The shared image definitions for OpenMesh devices are currently organized based on device families. This introduces some duplicate code, as the image creation code is mostly the same for those. This patch thus derives two basic shared definitions that work for all devices and only requires a few variables to be moved back to the device definitions. Signed-off-by: Adrian Schmutzler --- target/linux/ath79/image/generic.mk | 101 ++++++++++++++-------------- 1 file changed, 49 insertions(+), 52 deletions(-) diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk index fec7f06215..3d569c9532 100644 --- a/target/linux/ath79/image/generic.mk +++ b/target/linux/ath79/image/generic.mk @@ -8,6 +8,7 @@ DEVICE_VARS += ADDPATTERN_ID ADDPATTERN_VERSION DEVICE_VARS += SEAMA_SIGNATURE SEAMA_MTDBLOCK DEVICE_VARS += KERNEL_INITRAMFS_PREFIX DAP_SIGNATURE DEVICE_VARS += EDIMAX_HEADER_MAGIC EDIMAX_HEADER_MODEL +DEVICE_VARS += OPENMESH_CE_TYPE define Build/add-elecom-factory-initramfs $(eval edimax_model=$(word 1,$(1))) @@ -1525,148 +1526,144 @@ define Device/ocedo_ursus endef TARGET_DEVICES += ocedo_ursus -define Device/openmesh_mr600-common - SOC := ar9344 +define Device/openmesh_common_64k DEVICE_VENDOR := OpenMesh - DEVICE_MODEL := MR600 DEVICE_PACKAGES := uboot-envtools IMAGE_SIZE := 7808k BLOCKSIZE := 64k + OPENMESH_CE_TYPE := KERNEL := kernel-bin | append-dtb | lzma | uImage lzma | \ pad-to $$(BLOCKSIZE) IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | \ - openmesh-image ce_type=MR600 | append-metadata + openmesh-image ce_type=$$$$(OPENMESH_CE_TYPE) | append-metadata +endef + +define Device/openmesh_common_256k + DEVICE_VENDOR := OpenMesh + DEVICE_PACKAGES := uboot-envtools + IMAGE_SIZE := 7168k + BLOCKSIZE := 256k + OPENMESH_CE_TYPE := + KERNEL := kernel-bin | append-dtb | lzma | uImage lzma | \ + pad-to $$(BLOCKSIZE) + IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | \ + openmesh-image ce_type=$$$$(OPENMESH_CE_TYPE) | append-metadata endef define Device/openmesh_mr600-v1 - $(Device/openmesh_mr600-common) + $(Device/openmesh_common_64k) + SOC := ar9344 + DEVICE_MODEL := MR600 DEVICE_VARIANT := v1 + OPENMESH_CE_TYPE := MR600 SUPPORTED_DEVICES += mr600 endef TARGET_DEVICES += openmesh_mr600-v1 define Device/openmesh_mr600-v2 - $(Device/openmesh_mr600-common) + $(Device/openmesh_common_64k) + SOC := ar9344 + DEVICE_MODEL := MR600 DEVICE_VARIANT := v2 + OPENMESH_CE_TYPE := MR600 SUPPORTED_DEVICES += mr600v2 endef TARGET_DEVICES += openmesh_mr600-v2 -define Device/openmesh_mr900-common - SOC := qca9558 - DEVICE_VENDOR := OpenMesh - DEVICE_MODEL := MR900 - DEVICE_PACKAGES := uboot-envtools - IMAGE_SIZE := 7808k - BLOCKSIZE := 64k - KERNEL := kernel-bin | append-dtb | lzma | uImage lzma | \ - pad-to $$(BLOCKSIZE) - IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | \ - openmesh-image ce_type=MR900 | append-metadata -endef - define Device/openmesh_mr900-v1 - $(Device/openmesh_mr900-common) + $(Device/openmesh_common_64k) + SOC := qca9558 + DEVICE_MODEL := MR900 DEVICE_VARIANT := v1 + OPENMESH_CE_TYPE := MR900 SUPPORTED_DEVICES += mr900 endef TARGET_DEVICES += openmesh_mr900-v1 define Device/openmesh_mr900-v2 - $(Device/openmesh_mr900-common) + $(Device/openmesh_common_64k) + SOC := qca9558 + DEVICE_MODEL := MR900 DEVICE_VARIANT := v2 + OPENMESH_CE_TYPE := MR900 SUPPORTED_DEVICES += mr900v2 endef TARGET_DEVICES += openmesh_mr900-v2 -define Device/openmesh_om2p-common - DEVICE_VENDOR := OpenMesh - DEVICE_PACKAGES := uboot-envtools - IMAGE_SIZE := 7168k - BLOCKSIZE := 256k - KERNEL := kernel-bin | append-dtb | lzma | uImage lzma | \ - pad-to $$(BLOCKSIZE) - IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | \ - openmesh-image ce_type=OM2P | append-metadata -endef - define Device/openmesh_om2p-v2 - $(Device/openmesh_om2p-common) + $(Device/openmesh_common_256k) SOC := ar9330 DEVICE_MODEL := OM2P DEVICE_VARIANT := v2 + OPENMESH_CE_TYPE := OM2P SUPPORTED_DEVICES += om2pv2 endef TARGET_DEVICES += openmesh_om2p-v2 define Device/openmesh_om2p-v4 - $(Device/openmesh_om2p-common) + $(Device/openmesh_common_256k) SOC := qca9533 DEVICE_MODEL := OM2P DEVICE_VARIANT := v4 + OPENMESH_CE_TYPE := OM2P SUPPORTED_DEVICES += om2pv4 endef TARGET_DEVICES += openmesh_om2p-v4 define Device/openmesh_om2p-hs-v1 - $(Device/openmesh_om2p-common) + $(Device/openmesh_common_256k) SOC := ar9341 DEVICE_MODEL := OM2P-HS DEVICE_VARIANT := v1 + OPENMESH_CE_TYPE := OM2P SUPPORTED_DEVICES += om2p-hs endef TARGET_DEVICES += openmesh_om2p-hs-v1 define Device/openmesh_om2p-hs-v2 - $(Device/openmesh_om2p-common) + $(Device/openmesh_common_256k) SOC := ar9341 DEVICE_MODEL := OM2P-HS DEVICE_VARIANT := v2 + OPENMESH_CE_TYPE := OM2P SUPPORTED_DEVICES += om2p-hsv2 endef TARGET_DEVICES += openmesh_om2p-hs-v2 define Device/openmesh_om2p-hs-v3 - $(Device/openmesh_om2p-common) + $(Device/openmesh_common_256k) SOC := ar9341 DEVICE_MODEL := OM2P-HS DEVICE_VARIANT := v3 + OPENMESH_CE_TYPE := OM2P SUPPORTED_DEVICES += om2p-hsv3 endef TARGET_DEVICES += openmesh_om2p-hs-v3 define Device/openmesh_om2p-hs-v4 - $(Device/openmesh_om2p-common) + $(Device/openmesh_common_256k) SOC := qca9533 DEVICE_MODEL := OM2P-HS DEVICE_VARIANT := v4 + OPENMESH_CE_TYPE := OM2P SUPPORTED_DEVICES += om2p-hsv4 endef TARGET_DEVICES += openmesh_om2p-hs-v4 define Device/openmesh_om2p-lc - $(Device/openmesh_om2p-common) + $(Device/openmesh_common_256k) SOC := ar9330 DEVICE_MODEL := OM2P-LC + OPENMESH_CE_TYPE := OM2P SUPPORTED_DEVICES += om2p-lc endef TARGET_DEVICES += openmesh_om2p-lc -define Device/openmesh_om5p-common - SOC := ar9344 - DEVICE_VENDOR := OpenMesh - DEVICE_PACKAGES := uboot-envtools - IMAGE_SIZE := 7808k - BLOCKSIZE := 64k - KERNEL := kernel-bin | append-dtb | lzma | uImage lzma | \ - pad-to $$(BLOCKSIZE) - IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | \ - openmesh-image ce_type=OM5P | append-metadata -endef - define Device/openmesh_om5p - $(Device/openmesh_om5p-common) + $(Device/openmesh_common_64k) + SOC := ar9344 DEVICE_MODEL := OM5P + OPENMESH_CE_TYPE := OM5P SUPPORTED_DEVICES += om5p endef TARGET_DEVICES += openmesh_om5p From 847cda16eba23d4436a01b7313a21426b9c606fb Mon Sep 17 00:00:00 2001 From: Adrian Schmutzler Date: Tue, 19 Jan 2021 14:53:36 +0100 Subject: [PATCH 31/34] ath79: make OpenMesh MR900 DTSI more general The OpenMesh MR900 and to-be-added MR1750 family are very similar. Make the existing MR900 DTSI more general so it can be used for the MR1750 devices as well. Signed-off-by: Adrian Schmutzler --- ...sh_mr900.dtsi => qca9558_openmesh_mr.dtsi} | 13 ++----------- .../ath79/dts/qca9558_openmesh_mr900-v1.dts | 19 ++++++++++++++++++- .../ath79/dts/qca9558_openmesh_mr900-v2.dts | 19 ++++++++++++++++++- 3 files changed, 38 insertions(+), 13 deletions(-) rename target/linux/ath79/dts/{qca9558_openmesh_mr900.dtsi => qca9558_openmesh_mr.dtsi} (91%) diff --git a/target/linux/ath79/dts/qca9558_openmesh_mr900.dtsi b/target/linux/ath79/dts/qca9558_openmesh_mr.dtsi similarity index 91% rename from target/linux/ath79/dts/qca9558_openmesh_mr900.dtsi rename to target/linux/ath79/dts/qca9558_openmesh_mr.dtsi index 8c612042c8..d51c587683 100644 --- a/target/linux/ath79/dts/qca9558_openmesh_mr900.dtsi +++ b/target/linux/ath79/dts/qca9558_openmesh_mr.dtsi @@ -37,10 +37,9 @@ gpios = <&gpio 12 GPIO_ACTIVE_LOW>; }; - wifi2g_blue { + led_wifi2g: wifi2g { label = "blue:wifi2g"; gpios = <&gpio 13 GPIO_ACTIVE_LOW>; - linux,default-trigger = "phy0tpt"; }; status_green { @@ -59,10 +58,9 @@ default-state = "on"; }; - wifi5g_blue { + led_wifi5g: wifi5g { label = "blue:wifi5g"; gpios = <&gpio 23 GPIO_ACTIVE_LOW>; - linux,default-trigger = "phy1tpt"; }; }; @@ -168,11 +166,4 @@ &pcie0 { status = "okay"; - - wifi@0,0 { - compatible = "pci168c,0033"; - reg = <0x0000 0 0 0 0>; - mtd-mac-address = <&art 0x0>; - mtd-mac-address-increment = <16>; - }; }; diff --git a/target/linux/ath79/dts/qca9558_openmesh_mr900-v1.dts b/target/linux/ath79/dts/qca9558_openmesh_mr900-v1.dts index 96fc9853cb..f7889b00cc 100644 --- a/target/linux/ath79/dts/qca9558_openmesh_mr900-v1.dts +++ b/target/linux/ath79/dts/qca9558_openmesh_mr900-v1.dts @@ -1,8 +1,25 @@ // SPDX-License-Identifier: GPL-2.0-or-later OR MIT -#include "qca9558_openmesh_mr900.dtsi" +#include "qca9558_openmesh_mr.dtsi" / { compatible = "openmesh,mr900-v1", "qca,qca9558"; model = "OpenMesh MR900 v1"; }; + +&led_wifi2g { + linux,default-trigger = "phy0tpt"; +}; + +&led_wifi5g { + linux,default-trigger = "phy1tpt"; +}; + +&pcie0 { + wifi@0,0 { + compatible = "pci168c,0033"; + reg = <0x0000 0 0 0 0>; + mtd-mac-address = <&art 0x0>; + mtd-mac-address-increment = <16>; + }; +}; diff --git a/target/linux/ath79/dts/qca9558_openmesh_mr900-v2.dts b/target/linux/ath79/dts/qca9558_openmesh_mr900-v2.dts index 008caae2ec..1f54d2134a 100644 --- a/target/linux/ath79/dts/qca9558_openmesh_mr900-v2.dts +++ b/target/linux/ath79/dts/qca9558_openmesh_mr900-v2.dts @@ -1,8 +1,25 @@ // SPDX-License-Identifier: GPL-2.0-or-later OR MIT -#include "qca9558_openmesh_mr900.dtsi" +#include "qca9558_openmesh_mr.dtsi" / { compatible = "openmesh,mr900-v2", "qca,qca9558"; model = "OpenMesh MR900 v2"; }; + +&led_wifi2g { + linux,default-trigger = "phy0tpt"; +}; + +&led_wifi5g { + linux,default-trigger = "phy1tpt"; +}; + +&pcie0 { + wifi@0,0 { + compatible = "pci168c,0033"; + reg = <0x0000 0 0 0 0>; + mtd-mac-address = <&art 0x0>; + mtd-mac-address-increment = <16>; + }; +}; From ae7680dc4bf914d640dba32c8f1c36631768a56a Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 23 Nov 2020 13:41:34 +0100 Subject: [PATCH 32/34] ath79: Add support for OpenMesh MR1750 v1 Device specifications: ====================== * Qualcomm/Atheros QCA9558 ver 1 rev 0 * 720/600/240 MHz (CPU/DDR/AHB) * 128 MB of RAM * 16 MB of SPI NOR flash - 2x 7 MB available; but one of the 7 MB regions is the recovery image * 3T3R 2.4 GHz Wi-Fi (11n) * 3T3R 5 GHz Wi-Fi (11ac) * 6x GPIO-LEDs (2x wifi, 2x status, 1x lan, 1x power) * 1x GPIO-button (reset) * external h/w watchdog (enabled by default)) * TTL pins are on board (arrow points to VCC, then follows: GND, TX, RX) * 1x ethernet - AR8035 ethernet PHY (RGMII) - 10/100/1000 Mbps Ethernet - 802.3af POE - used as LAN interface * 12-24V 1A DC * internal antennas Flashing instructions: ====================== Various methods can be used to install the actual image on the flash. Two easy ones are: ap51-flash ---------- The tool ap51-flash (https://github.com/ap51-flash/ap51-flash) should be used to transfer the image to the u-boot when the device boots up. initramfs from TFTP ------------------- The serial console must be used to access the u-boot shell during bootup. It can then be used to first boot up the initramfs image from a TFTP server (here with the IP 192.168.1.21): setenv serverip 192.168.1.21 setenv ipaddr 192.168.1.1 tftpboot 0c00000 .bin && bootm $fileaddr The actual sysupgrade image can then be transferred (on the LAN port) to the device via scp .bin root@192.168.1.1:/tmp/ On the device, the sysupgrade must then be started using sysupgrade -n /tmp/.bin Signed-off-by: Sven Eckelmann [rebase, apply shared DTSI/device node, add LED migration] Signed-off-by: Adrian Schmutzler --- package/boot/uboot-envtools/files/ath79 | 1 + .../ath79/dts/qca9558_openmesh_mr1750-v1.dts | 16 ++++++++++++++++ .../ath79/generic/base-files/etc/board.d/01_leds | 3 ++- .../generic/base-files/etc/board.d/02_network | 1 + .../etc/hotplug.d/firmware/11-ath10k-caldata | 4 ++++ .../base-files/etc/uci-defaults/04_led_migration | 3 ++- .../generic/base-files/lib/upgrade/platform.sh | 1 + target/linux/ath79/image/generic.mk | 11 +++++++++++ 8 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 target/linux/ath79/dts/qca9558_openmesh_mr1750-v1.dts diff --git a/package/boot/uboot-envtools/files/ath79 b/package/boot/uboot-envtools/files/ath79 index 15994cec38..dfb77112a7 100644 --- a/package/boot/uboot-envtools/files/ath79 +++ b/package/boot/uboot-envtools/files/ath79 @@ -52,6 +52,7 @@ openmesh,mr600-v1|\ openmesh,mr600-v2|\ openmesh,mr900-v1|\ openmesh,mr900-v2|\ +openmesh,mr1750-v1|\ openmesh,om5p|\ openmesh,om5p-ac-v2|\ samsung,wam250|\ diff --git a/target/linux/ath79/dts/qca9558_openmesh_mr1750-v1.dts b/target/linux/ath79/dts/qca9558_openmesh_mr1750-v1.dts new file mode 100644 index 0000000000..11eb6dfb55 --- /dev/null +++ b/target/linux/ath79/dts/qca9558_openmesh_mr1750-v1.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca9558_openmesh_mr.dtsi" + +/ { + compatible = "openmesh,mr1750-v1", "qca,qca9558"; + model = "OpenMesh MR1750 v1"; +}; + +&led_wifi2g { + linux,default-trigger = "phy1tpt"; +}; + +&led_wifi5g { + linux,default-trigger = "phy0tpt"; +}; diff --git a/target/linux/ath79/generic/base-files/etc/board.d/01_leds b/target/linux/ath79/generic/base-files/etc/board.d/01_leds index 8fba9bc0e7..2cdad7dd77 100755 --- a/target/linux/ath79/generic/base-files/etc/board.d/01_leds +++ b/target/linux/ath79/generic/base-files/etc/board.d/01_leds @@ -159,7 +159,8 @@ comfast,cf-wr752ac-v1|\ engenius,eap300-v2|\ enterasys,ws-ap3705i|\ openmesh,mr900-v1|\ -openmesh,mr900-v2) +openmesh,mr900-v2|\ +openmesh,mr1750-v1) ucidef_set_led_netdev "lan" "LAN" "blue:lan" "eth0" ;; compex,wpj344-16m|\ diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network index 76bbd92c21..ef6b70c902 100755 --- a/target/linux/ath79/generic/base-files/etc/board.d/02_network +++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network @@ -50,6 +50,7 @@ ath79_setup_interfaces() openmesh,mr600-v2|\ openmesh,mr900-v1|\ openmesh,mr900-v2|\ + openmesh,mr1750-v1|\ pcs,cap324|\ pisen,ts-d084|\ pisen,wmb001n|\ diff --git a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/11-ath10k-caldata index 99d2353ac1..d1a4767648 100644 --- a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/11-ath10k-caldata +++ b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/11-ath10k-caldata @@ -96,6 +96,10 @@ case "$FIRMWARE" in caldata_extract "art" 0x5000 0x844 ath10k_patch_mac $(mtd_get_mac_binary art 0xc) ;; + openmesh,mr1750-v1) + caldata_extract "ART" 0x5000 0x844 + ath10k_patch_mac $(macaddr_add $(cat /sys/class/net/eth0/address) +16) + ;; openmesh,om5p-ac-v2) caldata_extract "art" 0x5000 0x844 ath10k_patch_mac $(macaddr_add $(cat /sys/class/net/eth0/address) +16) diff --git a/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration b/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration index 453bf3b911..1d8909f688 100644 --- a/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration +++ b/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration @@ -24,7 +24,8 @@ openmesh,mr600-v2) migrate_leds ":wlan24=:wifi2g" ":wlan58=:wifi5g" ;; openmesh,mr900-v1|\ -openmesh,mr900-v2) +openmesh,mr900-v2|\ +openmesh,mr1750-v1) migrate_leds ":wlan24=:wifi2g" ":wlan58=:wifi5g" ":wan=:lan" ;; pcs,cap324) diff --git a/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh b/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh index 76512758b6..01a9f61943 100644 --- a/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh +++ b/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh @@ -54,6 +54,7 @@ platform_do_upgrade() { openmesh,mr600-v2|\ openmesh,mr900-v1|\ openmesh,mr900-v2|\ + openmesh,mr1750-v1|\ openmesh,om2p-v2|\ openmesh,om2p-v4|\ openmesh,om2p-hs-v1|\ diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk index 3d569c9532..92e9458b37 100644 --- a/target/linux/ath79/image/generic.mk +++ b/target/linux/ath79/image/generic.mk @@ -1590,6 +1590,17 @@ define Device/openmesh_mr900-v2 endef TARGET_DEVICES += openmesh_mr900-v2 +define Device/openmesh_mr1750-v1 + $(Device/openmesh_common_64k) + SOC := qca9558 + DEVICE_MODEL := MR1750 + DEVICE_VARIANT := v1 + DEVICE_PACKAGES += kmod-ath10k-ct ath10k-firmware-qca988x-ct + OPENMESH_CE_TYPE := MR1750 + SUPPORTED_DEVICES += mr1750 +endef +TARGET_DEVICES += openmesh_mr1750-v1 + define Device/openmesh_om2p-v2 $(Device/openmesh_common_256k) SOC := ar9330 From 0988e03f0e676286f3377d1530ebfb0d819ee629 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 23 Nov 2020 13:41:34 +0100 Subject: [PATCH 33/34] ath79: Add support for OpenMesh MR1750 v2 Device specifications: ====================== * Qualcomm/Atheros QCA9558 ver 1 rev 0 * 720/600/240 MHz (CPU/DDR/AHB) * 128 MB of RAM * 16 MB of SPI NOR flash - 2x 7 MB available; but one of the 7 MB regions is the recovery image * 3T3R 2.4 GHz Wi-Fi (11n) * 3T3R 5 GHz Wi-Fi (11ac) * 6x GPIO-LEDs (2x wifi, 2x status, 1x lan, 1x power) * 1x GPIO-button (reset) * external h/w watchdog (enabled by default)) * TTL pins are on board (arrow points to VCC, then follows: GND, TX, RX) * 1x ethernet - AR8035 ethernet PHY (RGMII) - 10/100/1000 Mbps Ethernet - 802.3af POE - used as LAN interface * 12-24V 1A DC * internal antennas Flashing instructions: ====================== Various methods can be used to install the actual image on the flash. Two easy ones are: ap51-flash ---------- The tool ap51-flash (https://github.com/ap51-flash/ap51-flash) should be used to transfer the image to the u-boot when the device boots up. initramfs from TFTP ------------------- The serial console must be used to access the u-boot shell during bootup. It can then be used to first boot up the initramfs image from a TFTP server (here with the IP 192.168.1.21): setenv serverip 192.168.1.21 setenv ipaddr 192.168.1.1 tftpboot 0c00000 .bin && bootm $fileaddr The actual sysupgrade image can then be transferred (on the LAN port) to the device via scp .bin root@192.168.1.1:/tmp/ On the device, the sysupgrade must then be started using sysupgrade -n /tmp/.bin Signed-off-by: Sven Eckelmann [rebase, add LED migration] Signed-off-by: Adrian Schmutzler --- package/boot/uboot-envtools/Makefile | 2 +- package/boot/uboot-envtools/files/ath79 | 1 + .../ath79/dts/qca9558_openmesh_mr1750-v2.dts | 16 ++++++++++++++++ .../ath79/generic/base-files/etc/board.d/01_leds | 3 ++- .../generic/base-files/etc/board.d/02_network | 1 + .../etc/hotplug.d/firmware/11-ath10k-caldata | 3 ++- .../base-files/etc/uci-defaults/04_led_migration | 3 ++- .../generic/base-files/lib/upgrade/platform.sh | 1 + target/linux/ath79/image/generic.mk | 11 +++++++++++ 9 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 target/linux/ath79/dts/qca9558_openmesh_mr1750-v2.dts diff --git a/package/boot/uboot-envtools/Makefile b/package/boot/uboot-envtools/Makefile index fb025c95ea..dda9d6be9c 100644 --- a/package/boot/uboot-envtools/Makefile +++ b/package/boot/uboot-envtools/Makefile @@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=uboot-envtools PKG_DISTNAME:=u-boot PKG_VERSION:=2020.04 -PKG_RELEASE:=19 +PKG_RELEASE:=20 PKG_SOURCE:=$(PKG_DISTNAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:= \ diff --git a/package/boot/uboot-envtools/files/ath79 b/package/boot/uboot-envtools/files/ath79 index dfb77112a7..4b84766814 100644 --- a/package/boot/uboot-envtools/files/ath79 +++ b/package/boot/uboot-envtools/files/ath79 @@ -53,6 +53,7 @@ openmesh,mr600-v2|\ openmesh,mr900-v1|\ openmesh,mr900-v2|\ openmesh,mr1750-v1|\ +openmesh,mr1750-v2|\ openmesh,om5p|\ openmesh,om5p-ac-v2|\ samsung,wam250|\ diff --git a/target/linux/ath79/dts/qca9558_openmesh_mr1750-v2.dts b/target/linux/ath79/dts/qca9558_openmesh_mr1750-v2.dts new file mode 100644 index 0000000000..0271db0802 --- /dev/null +++ b/target/linux/ath79/dts/qca9558_openmesh_mr1750-v2.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca9558_openmesh_mr.dtsi" + +/ { + compatible = "openmesh,mr1750-v2", "qca,qca9558"; + model = "OpenMesh MR1750 v2"; +}; + +&led_wifi2g { + linux,default-trigger = "phy1tpt"; +}; + +&led_wifi5g { + linux,default-trigger = "phy0tpt"; +}; diff --git a/target/linux/ath79/generic/base-files/etc/board.d/01_leds b/target/linux/ath79/generic/base-files/etc/board.d/01_leds index 2cdad7dd77..c6ade98c8f 100755 --- a/target/linux/ath79/generic/base-files/etc/board.d/01_leds +++ b/target/linux/ath79/generic/base-files/etc/board.d/01_leds @@ -160,7 +160,8 @@ engenius,eap300-v2|\ enterasys,ws-ap3705i|\ openmesh,mr900-v1|\ openmesh,mr900-v2|\ -openmesh,mr1750-v1) +openmesh,mr1750-v1|\ +openmesh,mr1750-v2) ucidef_set_led_netdev "lan" "LAN" "blue:lan" "eth0" ;; compex,wpj344-16m|\ diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network index ef6b70c902..0c08871f99 100755 --- a/target/linux/ath79/generic/base-files/etc/board.d/02_network +++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network @@ -51,6 +51,7 @@ ath79_setup_interfaces() openmesh,mr900-v1|\ openmesh,mr900-v2|\ openmesh,mr1750-v1|\ + openmesh,mr1750-v2|\ pcs,cap324|\ pisen,ts-d084|\ pisen,wmb001n|\ diff --git a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/11-ath10k-caldata index d1a4767648..84323046f6 100644 --- a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/11-ath10k-caldata +++ b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/11-ath10k-caldata @@ -96,7 +96,8 @@ case "$FIRMWARE" in caldata_extract "art" 0x5000 0x844 ath10k_patch_mac $(mtd_get_mac_binary art 0xc) ;; - openmesh,mr1750-v1) + openmesh,mr1750-v1|\ + openmesh,mr1750-v2) caldata_extract "ART" 0x5000 0x844 ath10k_patch_mac $(macaddr_add $(cat /sys/class/net/eth0/address) +16) ;; diff --git a/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration b/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration index 1d8909f688..ea5cafa66b 100644 --- a/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration +++ b/target/linux/ath79/generic/base-files/etc/uci-defaults/04_led_migration @@ -25,7 +25,8 @@ openmesh,mr600-v2) ;; openmesh,mr900-v1|\ openmesh,mr900-v2|\ -openmesh,mr1750-v1) +openmesh,mr1750-v1|\ +openmesh,mr1750-v2) migrate_leds ":wlan24=:wifi2g" ":wlan58=:wifi5g" ":wan=:lan" ;; pcs,cap324) diff --git a/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh b/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh index 01a9f61943..575761d079 100644 --- a/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh +++ b/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh @@ -55,6 +55,7 @@ platform_do_upgrade() { openmesh,mr900-v1|\ openmesh,mr900-v2|\ openmesh,mr1750-v1|\ + openmesh,mr1750-v2|\ openmesh,om2p-v2|\ openmesh,om2p-v4|\ openmesh,om2p-hs-v1|\ diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk index 92e9458b37..3b5cb6bdfa 100644 --- a/target/linux/ath79/image/generic.mk +++ b/target/linux/ath79/image/generic.mk @@ -1601,6 +1601,17 @@ define Device/openmesh_mr1750-v1 endef TARGET_DEVICES += openmesh_mr1750-v1 +define Device/openmesh_mr1750-v2 + $(Device/openmesh_common_64k) + SOC := qca9558 + DEVICE_MODEL := MR1750 + DEVICE_VARIANT := v2 + DEVICE_PACKAGES += kmod-ath10k-ct ath10k-firmware-qca988x-ct + OPENMESH_CE_TYPE := MR1750 + SUPPORTED_DEVICES += mr1750v2 +endef +TARGET_DEVICES += openmesh_mr1750-v2 + define Device/openmesh_om2p-v2 $(Device/openmesh_common_256k) SOC := ar9330 From 1bd005ea53a7844808881bacda45f9fbc60b805b Mon Sep 17 00:00:00 2001 From: John Audia Date: Tue, 19 Jan 2021 16:13:26 -0500 Subject: [PATCH 34/34] kernel: bump 5.4 to 5.4.91 All modification made by update_kernel.sh in a fresh clone without existing toolchains. Build system: x86_64 Build-tested: ipq806x/R7800, bcm27xx/bcm2711 Run-tested: ipq806x/R7800 No dmesg regressions, everything functional Signed-off-by: John Audia Tested-by: Curtis Deptuck [x86/64] --- include/kernel-version.mk | 4 ++-- .../pending-5.4/613-netfilter_optional_tcp_window_check.patch | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/kernel-version.mk b/include/kernel-version.mk index acd651f9ed..5f8614f060 100644 --- a/include/kernel-version.mk +++ b/include/kernel-version.mk @@ -6,9 +6,9 @@ ifdef CONFIG_TESTING_KERNEL KERNEL_PATCHVER:=$(KERNEL_TESTING_PATCHVER) endif -LINUX_VERSION-5.4 = .90 +LINUX_VERSION-5.4 = .91 -LINUX_KERNEL_HASH-5.4.90 = 646736bc063f181c22648934f0dc3d97d49aec6edfd7358d2fe3df29fb66fa1a +LINUX_KERNEL_HASH-5.4.91 = 0e0161bb034b9ba59e58a20985e49ecfb38104586602f53f37b382f508fc5c17 remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1)))) sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1))))))) diff --git a/target/linux/generic/pending-5.4/613-netfilter_optional_tcp_window_check.patch b/target/linux/generic/pending-5.4/613-netfilter_optional_tcp_window_check.patch index 711ffcd838..2881337724 100644 --- a/target/linux/generic/pending-5.4/613-netfilter_optional_tcp_window_check.patch +++ b/target/linux/generic/pending-5.4/613-netfilter_optional_tcp_window_check.patch @@ -49,7 +49,7 @@ Signed-off-by: Felix Fietkau static bool enable_hooks __read_mostly; MODULE_PARM_DESC(enable_hooks, "Always enable conntrack hooks"); module_param(enable_hooks, bool, 0000); -@@ -646,6 +649,7 @@ enum nf_ct_sysctl_index { +@@ -649,6 +652,7 @@ enum nf_ct_sysctl_index { NF_SYSCTL_CT_PROTO_TIMEOUT_GRE_STREAM, #endif @@ -57,7 +57,7 @@ Signed-off-by: Felix Fietkau __NF_SYSCTL_CT_LAST_SYSCTL, }; -@@ -972,6 +976,13 @@ static struct ctl_table nf_ct_sysctl_tab +@@ -975,6 +979,13 @@ static struct ctl_table nf_ct_sysctl_tab .proc_handler = proc_dointvec_jiffies, }, #endif