diff --git a/config/Config-build.in b/config/Config-build.in index 196d4e67a..c2303637c 100644 --- a/config/Config-build.in +++ b/config/Config-build.in @@ -14,14 +14,14 @@ config EXPERIMENTAL positive and negative). But do so only if you know how to recover your device in case of flashing potentially non-working firmware. - + If you plan to use this build in production, say NO! menu "Global build settings" config JSON_OVERVIEW_IMAGE_INFO bool "Create JSON info file overview per target" - default BUILDBOT + default y help Create a JSON info file called profiles.json in the target directory containing machine readable list of built profiles @@ -111,7 +111,7 @@ menu "Global build settings" default n help This makes file checksums part of package metadata. It increases size - but provides you with pkg_check command to check for flash coruptions. + but provides you with pkg_check command to check for flash corruptions. config INCLUDE_CONFIG bool "Include build configuration in firmware" if DEVEL @@ -154,17 +154,12 @@ menu "Global build settings" Adds -g3 to the CFLAGS. config IPV6 - bool - prompt "Enable IPv6 support in packages" - default y - help - Enables IPv6 support in kernel (builtin) and packages. + def_bool y comment "Stripping options" choice prompt "Binary stripping method" - default USE_STRIP if EXTERNAL_TOOLCHAIN default USE_STRIP if USE_GLIBC default USE_SSTRIP help @@ -221,20 +216,6 @@ menu "Global build settings" make the system libraries incompatible with most of the packages that are not selected during the build process. - choice - prompt "Preferred standard C++ library" - default USE_LIBSTDCXX if USE_GLIBC - default USE_UCLIBCXX - help - Select the preferred standard C++ library for all packages that support this. - - config USE_UCLIBCXX - bool "uClibc++" - - config USE_LIBSTDCXX - bool "libstdc++" - endchoice - comment "Hardening build options" config PKG_CHECK_FORMAT_SECURITY @@ -390,4 +371,16 @@ menu "Global build settings" endchoice + config SECCOMP + bool "Enable SECCOMP" + select KERNEL_SECCOMP + select PACKAGE_procd-seccomp + depends on (aarch64 || arm || armeb || mips || mipsel || mips64 || mips64el || i386 || powerpc || x86_64) + depends on !TARGET_uml + default y + help + This option enables seccomp kernel features to safely + execute untrusted bytecode and selects the seccomp-variants + of procd + endmenu diff --git a/config/Config-devel.in b/config/Config-devel.in index 4c40817c5..e16e6ecaa 100644 --- a/config/Config-devel.in +++ b/config/Config-devel.in @@ -95,6 +95,11 @@ menuconfig DEVEL Store ccache in this directory. If not set, uses './.ccache' + config KERNEL_CFLAGS + string "Kernel extra CFLAGS" if DEVEL + default "-falign-functions=32" if TARGET_bcm53xx + default "" + config EXTERNAL_KERNEL_TREE string "Use external kernel tree" if DEVEL default "" diff --git a/config/Config-images.in b/config/Config-images.in index 891195c09..6c1408614 100644 --- a/config/Config-images.in +++ b/config/Config-images.in @@ -48,6 +48,7 @@ menu "Target Images" bool "xz" config TARGET_INITRAMFS_COMPRESSION_ZSTD + depends on !LINUX_5_4 bool "zstd" endchoice @@ -151,7 +152,7 @@ menu "Target Images" bool "squashfs" default y if USES_SQUASHFS help - Build a squashfs-lzma root filesystem. + Build a squashfs root filesystem. config TARGET_SQUASHFS_BLOCK_SIZE int "Block size (in KiB)" @@ -159,6 +160,9 @@ menu "Target Images" default 64 if LOW_MEMORY_FOOTPRINT default 1024 if (SMALL_FLASH && !LOW_MEMORY_FOOTPRINT) default 1024 + help + Select squashfs block size, must be one of: + 4, 8, 16, 32, 64, 128, 256, 512, 1024 menuconfig TARGET_ROOTFS_UBIFS bool "ubifs" @@ -293,7 +297,7 @@ menu "Target Images" source "target/linux/*/image/Config.in" config TARGET_KERNEL_PARTSIZE - int "Kernel partition size (in MB)" + int "Kernel partition size (in MiB)" depends on USES_BOOT_PART default 8 if TARGET_apm821xx_sata default 64 if TARGET_bcm27xx @@ -301,8 +305,8 @@ menu "Target Images" default 16 config TARGET_ROOTFS_PARTSIZE - int "Root filesystem partition size (in MB)" - depends on USES_ROOTFS_PART || TARGET_ROOTFS_EXT4FS || TARGET_omap || TARGET_sunxi || TARGET_uml + int "Root filesystem partition size (in MiB)" + depends on USES_ROOTFS_PART || TARGET_ROOTFS_EXT4FS default 400 help Select the root filesystem partition size. diff --git a/config/Config-kernel.in b/config/Config-kernel.in index 7c6e0e5a8..b6177421c 100644 --- a/config/Config-kernel.in +++ b/config/Config-kernel.in @@ -24,11 +24,6 @@ config KERNEL_PRINTK bool "Enable support for printk" default y -config KERNEL_CRASHLOG - bool "Crash logging" - depends on !(arm || powerpc || sparc || TARGET_uml || i386 || x86_64) - default y - config KERNEL_SWAP bool "Support for paging of anonymous memory (swap)" default y if !SMALL_FLASH @@ -48,8 +43,7 @@ config KERNEL_DEBUG_FS config KERNEL_MIPS_FP_SUPPORT bool - default y - depends on (mips || mipsel || mips64 || mips64el) + default y if TARGET_pistachio config KERNEL_ARM_PMU bool @@ -87,6 +81,11 @@ config KERNEL_PROFILING Enable the extended profiling support mechanisms used by profilers such as OProfile. +config KERNEL_RPI_AXIPERF + bool "Compile the kernel with RaspberryPi AXI Performance monitors" + default y + depends on KERNEL_PERF_EVENTS && TARGET_bcm27xx + config KERNEL_UBSAN bool "Compile the kernel with undefined behaviour sanity checker" help @@ -115,6 +114,16 @@ config KERNEL_UBSAN_ALIGNMENT Enabling this option on architectures that support unaligned accesses may produce a lot of false positives. +config KERNEL_UBSAN_BOUNDS + bool "Perform array index bounds checking" + depends on KERNEL_UBSAN + help + This option enables detection of directly indexed out of bounds array + accesses, where the array size is known at compile time. Note that + this does not protect array overflows via bad calls to the + {str,mem}*cpy() family of functions (that is addressed by + FORTIFY_SOURCE). + config KERNEL_UBSAN_NULL bool "Enable checking of null pointers" depends on KERNEL_UBSAN @@ -122,6 +131,19 @@ config KERNEL_UBSAN_NULL This option enables detection of memory accesses via a null pointer. +config KERNEL_UBSAN_TRAP + bool "On Sanitizer warnings, abort the running kernel code" + depends on KERNEL_UBSAN + help + Building kernels with Sanitizer features enabled tends to grow the + kernel size by around 5%, due to adding all the debugging text on + failure paths. To avoid this, Sanitizer instrumentation can just + issue a trap. This reduces the kernel size overhead but turns all + warnings (including potentially harmless conditions) into full + exceptions that abort the running kernel code (regardless of context, + locks held, etc), which may destabilize the system. For some system + builders this is an acceptable trade-off. + config KERNEL_KASAN bool "Compile the kernel with KASan: runtime memory debugger" select KERNEL_SLUB_DEBUG @@ -148,6 +170,30 @@ config KERNEL_KASAN_EXTRA compile time. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 has more +config KERNEL_KASAN_VMALLOC + bool "Back mappings in vmalloc space with real shadow memory" + depends on KERNEL_KASAN + help + By default, the shadow region for vmalloc space is the read-only + zero page. This means that KASAN cannot detect errors involving + vmalloc space. + + Enabling this option will hook in to vmap/vmalloc and back those + mappings with real shadow memory allocated on demand. This allows + for KASAN to detect more sorts of errors (and to support vmapped + stacks), but at the cost of higher memory usage. + + This option depends on HAVE_ARCH_KASAN_VMALLOC, but we can't + depend on that in here, so it is possible that enabling this + will have no effect. + +if KERNEL_KASAN + config KERNEL_KASAN_GENERIC + def_bool y + + config KERNEL_KASAN_SW_TAGS + def_bool n +endif choice prompt "Instrumentation type" @@ -303,6 +349,19 @@ config KERNEL_PREEMPT_TRACER enabled. This option and the irqs-off timing option can be used together or separately.) +config KERNEL_HIST_TRIGGERS + bool "Histogram triggers" + depends on KERNEL_FTRACE + help + Hist triggers allow one or more arbitrary trace event fields to be + aggregated into hash tables and dumped to stdout by reading a + debugfs/tracefs file. They're useful for gathering quick and dirty + (though precise) summaries of event activity as an initial guide for + further investigation using more advanced tools. + + Inter-event tracing of quantities such as latencies is also + supported using hist triggers under this option. + config KERNEL_DEBUG_KERNEL bool default n @@ -314,6 +373,34 @@ config KERNEL_DEBUG_INFO help This will compile your kernel and modules with debug information. +config KERNEL_DEBUG_INFO_BTF + + bool "Enable additional BTF type information" + default n + depends on !HOST_OS_MACOS + depends on KERNEL_DEBUG_INFO && !KERNEL_DEBUG_INFO_REDUCED + select DWARVES + help + Generate BPF Type Format (BTF) information from DWARF debug info. + Turning this on expects presence of pahole tool, which will convert + DWARF type info into equivalent deduplicated BTF type info. + + Required to run BPF CO-RE applications. + +config KERNEL_DEBUG_INFO_REDUCED + bool "Reduce debugging information" + default y + depends on KERNEL_DEBUG_INFO + help + If you say Y here gcc is instructed to generate less debugging + information for structure types. This means that tools that + need full debugging information (like kgdb or systemtap) won't + be happy. But if you merely need debugging information to + resolve line numbers there is no loss. Advantage is that + build directory object sizes shrink dramatically over a full + DEBUG_INFO build and compile times are reduced too. + Only works with newer gcc versions. + config KERNEL_DEBUG_LL_UART_NONE bool default n @@ -327,6 +414,14 @@ config KERNEL_DEBUG_LL help ARM low level debugging. +config KERNEL_DEBUG_VIRTUAL + bool "Compile the kernel with VM translations debugging" + select KERNEL_DEBUG_KERNEL + default n + help + Enable checks sanity checks to catch invalid uses of + virt_to_phys()/phys_to_virt() against the non-linear address space. + config KERNEL_DYNAMIC_DEBUG bool "Compile the kernel with dynamic printk" select KERNEL_DEBUG_FS @@ -368,6 +463,21 @@ config KERNEL_KPROBE_EVENTS bool default y if KERNEL_KPROBES +config KERNEL_BPF_EVENTS + bool "Compile the kernel with BPF event support" + default n + select KERNEL_KPROBES + help + Allows to attach BPF programs to kprobe, uprobe and tracepoint events. + This is required to use BPF maps of type BPF_MAP_TYPE_PERF_EVENT_ARRAY + for sending data from BPF programs to user-space for post-processing + or logging. + +config KERNEL_BPF_KPROBE_OVERRIDE + bool + default n + depends on KERNEL_KPROBES + config KERNEL_AIO bool "Compile the kernel with asynchronous IO support" default y if !SMALL_FLASH @@ -437,34 +547,22 @@ config KERNEL_PROVE_LOCKING select KERNEL_DEBUG_KERNEL default n -config KERNEL_LOCKUP_DETECTOR - bool "Compile the kernel with detect Hard and Soft Lockups" +config KERNEL_SOFTLOCKUP_DETECTOR + bool "Compile the kernel with detect Soft Lockups" depends on KERNEL_DEBUG_KERNEL help Say Y here to enable the kernel to act as a watchdog to detect - hard and soft lockups. + soft lockups. Softlockups are bugs that cause the kernel to loop in kernel mode for more than 20 seconds, without giving other tasks a chance to run. The current stack trace is displayed upon detection and the system will stay locked up. - Hardlockups are bugs that cause the CPU to loop in kernel mode - for more than 10 seconds, without letting other interrupts have a - chance to run. The current stack trace is displayed upon detection - and the system will stay locked up. - - The overhead should be minimal. A periodic hrtimer runs to - generate interrupts and kick the watchdog task every 4 seconds. - An NMI is generated every 10 seconds or so to check for hardlockups. - - The frequency of hrtimer and NMI events and the soft and hard lockup - thresholds can be controlled through the sysctl watchdog_thresh. - config KERNEL_DETECT_HUNG_TASK bool "Compile the kernel with detect Hung Tasks" depends on KERNEL_DEBUG_KERNEL - default KERNEL_LOCKUP_DETECTOR + default KERNEL_SOFTLOCKUP_DETECTOR help Say Y here to enable the kernel to detect "hung tasks", which are bugs that cause the task to be stuck in @@ -944,6 +1042,19 @@ config KERNEL_IP_MROUTE Multicast routing requires a multicast routing daemon in addition to kernel support. +if KERNEL_IP_MROUTE + + config KERNEL_IP_MROUTE_MULTIPLE_TABLES + def_bool y + + config KERNEL_IP_PIMSM_V1 + def_bool y + + config KERNEL_IP_PIMSM_V2 + def_bool y + +endif + # # IPv6 configuration # @@ -966,8 +1077,15 @@ if KERNEL_IPV6 Multicast routing requires a multicast routing daemon in addition to kernel support. - config KERNEL_IPV6_PIMSM_V2 - def_bool n + if KERNEL_IPV6_MROUTE + + config KERNEL_IPV6_MROUTE_MULTIPLE_TABLES + def_bool y + + config KERNEL_IPV6_PIMSM_V2 + def_bool y + + endif config KERNEL_IPV6_SEG6_LWTUNNEL bool "Enable support for lightweight tunnels" @@ -980,6 +1098,16 @@ if KERNEL_IPV6 endif +# +# Miscellaneous network configuration +# + +config KERNEL_NET_L3_MASTER_DEV + bool "L3 Master device support" + help + This module provides glue between core networking code and device + drivers to support L3 master devices like VRF. + # # NFS related symbols # @@ -1125,7 +1253,7 @@ config KERNEL_SQUASHFS_XATTR bool "Squashfs XATTR support" # -# compile optimiziation setting +# compile optimization setting # choice prompt "Compiler optimization level" diff --git a/feeds.conf.default b/feeds.conf.default index b48323f7f..14419ee39 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -1,7 +1,9 @@ -src-git packages https://github.com/DHDAXCW/packages -src-git luci https://github.com/DHDAXCW/luci +src-git packages https://github.com/coolsnowwolf/packages +src-git luci https://github.com/coolsnowwolf/luci src-git routing https://github.com/coolsnowwolf/routing src-git telephony https://git.openwrt.org/feed/telephony.git +#src-git helloworld https://github.com/fw876/helloworld.git +#src-git oui https://github.com/zhaojh329/oui.git #src-git video https://github.com/openwrt/video.git #src-git targets https://github.com/openwrt/targets.git #src-git oldpackages http://git.openwrt.org/packages.git diff --git a/include/autotools.mk b/include/autotools.mk index 2bdc43fd2..f659bac3c 100644 --- a/include/autotools.mk +++ b/include/autotools.mk @@ -35,7 +35,7 @@ define autoreconf $(patsubst %,rm -f %;,$(2)) \ $(foreach p,$(3), \ if [ -f $(p)/configure.ac ] || [ -f $(p)/configure.in ]; then \ - [ -d $(p)/autom4te.cache ] && rm -rf autom4te.cache; \ + [ -d $(p)/autom4te.cache ] && rm -rf $(p)/autom4te.cache; \ [ -e $(p)/config.rpath ] || \ ln -s $(SCRIPT_DIR)/config.rpath $(p)/config.rpath; \ touch NEWS AUTHORS COPYING ABOUT-NLS ChangeLog; \ diff --git a/include/bpf.mk b/include/bpf.mk index 871ca2aa5..e43fcad50 100644 --- a/include/bpf.mk +++ b/include/bpf.mk @@ -64,14 +64,14 @@ BPF_CFLAGS := \ -O2 -emit-llvm -Xclang -disable-llvm-passes ifneq ($(CONFIG_HAS_BPF_TOOLCHAIN),) - ifeq ($(DUMP),) - CLANG_VER:=$(shell $(CLANG) -dM -E - < /dev/null | grep __clang_major__ | cut -d' ' -f3) - CLANG_VER_VALID:=$(shell [ "$(CLANG_VER)" -ge "$(CLANG_MIN_VER)" ] && echo 1 ) - ifeq ($(CLANG_VER_VALID),) - $(error ERROR: LLVM/clang version too old. Minimum required: $(CLANG_MIN_VER), found: $(CLANG_VER)) - endif +ifeq ($(DUMP),) + CLANG_VER:=$(shell $(CLANG) -dM -E - < /dev/null | grep __clang_major__ | cut -d' ' -f3) + CLANG_VER_VALID:=$(shell [ "$(CLANG_VER)" -ge "$(CLANG_MIN_VER)" ] && echo 1 ) + ifeq ($(CLANG_VER_VALID),) + $(error ERROR: LLVM/clang version too old. Minimum required: $(CLANG_MIN_VER), found: $(CLANG_VER)) endif endif +endif define CompileBPF $(CLANG) -g -target $(BPF_ARCH)-linux-gnu $(BPF_CFLAGS) $(2) \ diff --git a/include/image-commands.mk b/include/image-commands.mk index f38c9a176..407dffa0c 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -53,6 +53,7 @@ define Build/append-image-stage cp "$(BIN_DIR)/$(DEVICE_IMG_PREFIX)-$(1)" "$@.stripmeta" fwtool -s /dev/null -t "$@.stripmeta" || : fwtool -i /dev/null -t "$@.stripmeta" || : + mkdir -p "$(STAGING_DIR_IMAGE)" dd if="$@.stripmeta" of="$(STAGING_DIR_IMAGE)/$(BOARD)$(if $(SUBTARGET),-$(SUBTARGET))-$(DEVICE_NAME)-$(1)" dd if="$@.stripmeta" >> "$@" rm "$@.stripmeta" @@ -305,8 +306,13 @@ define Build/fit @mv $@.new $@ endef +define Build/libdeflate-gzip + $(STAGING_DIR_HOST)/bin/libdeflate-gzip -f -12 -c $@ $(1) > $@.new + @mv $@.new $@ +endef + define Build/gzip - gzip -f -9n -c $@ $(1) > $@.new + $(STAGING_DIR_HOST)/bin/gzip -f -9n -c $@ $(1) > $@.new @mv $@.new $@ endef diff --git a/include/image.mk b/include/image.mk index e9dc53f82..5d9d4acb4 100644 --- a/include/image.mk +++ b/include/image.mk @@ -520,6 +520,7 @@ define Device/Build/compile $$(_COMPILE_TARGET): $(KDIR)/$(1) $(eval $(call Device/Export,$(KDIR)/$(1))) $(KDIR)/$(1): FORCE + rm -f $(KDIR)/$(1) $$(call concat_cmd,$(COMPILE/$(1))) endef diff --git a/include/kernel-5.10 b/include/kernel-5.10 index e52f4b1c4..a11908aae 100644 --- a/include/kernel-5.10 +++ b/include/kernel-5.10 @@ -1,2 +1,2 @@ -LINUX_VERSION-5.10 = .142 -LINUX_KERNEL_HASH-5.10.142 = 3f47ebdb9afe152a0c32c1157336ef13fa5cc08ac6d884dfc1f6ddc2b7dba268 +LINUX_VERSION-5.10 = .164 +LINUX_KERNEL_HASH-5.10.164 = 0c7eaaa87b012c6662440f4ce2ea6e1bb961c1845cafd102eab08a57efeb8278 diff --git a/include/kernel-5.15 b/include/kernel-5.15 index 8ebccec7f..82d1c5a7b 100644 --- a/include/kernel-5.15 +++ b/include/kernel-5.15 @@ -1,2 +1,2 @@ -LINUX_VERSION-5.15 = .67 -LINUX_KERNEL_HASH-5.15.67 = da47d9a80b694548835ccb553b6eb1a1f3f5d5cddd9e2bd6f4886b99ca14f940 +LINUX_VERSION-5.15 = .89 +LINUX_KERNEL_HASH-5.15.89 = e7311b874e014bb6d37c051319bd6a4a4e3d05a1c32546522deabbfd2d752fe8 diff --git a/include/kernel.mk b/include/kernel.mk index 2efa3bf8f..c657bf5d8 100644 --- a/include/kernel.mk +++ b/include/kernel.mk @@ -130,7 +130,7 @@ ifneq ($(HOST_OS),Linux) export SKIP_STACK_VALIDATION:=1 endif -KERNEL_MAKEOPTS := -C $(LINUX_DIR) $(KERNEL_MAKE_FLAGS) +KERNEL_MAKEOPTS = -C $(LINUX_DIR) $(KERNEL_MAKE_FLAGS) ifdef CONFIG_USE_SPARSE KERNEL_MAKEOPTS += C=1 CHECK=$(STAGING_DIR_HOST)/bin/sparse diff --git a/include/netfilter.mk b/include/netfilter.mk index e35c58d62..92dbf5e1c 100644 --- a/include/netfilter.mk +++ b/include/netfilter.mk @@ -230,11 +230,6 @@ $(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_CONNTRACK_IRC, $(P_XT)nf_connt $(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_NAT_IRC, $(P_XT)nf_nat_irc)) -# ulog - -$(eval $(call nf_add,IPT_ULOG,CONFIG_IP_NF_TARGET_ULOG, $(P_V4)ipt_ULOG)) - - # nflog $(eval $(call nf_add,IPT_NFLOG,CONFIG_NETFILTER_XT_TARGET_NFLOG, $(P_XT)xt_NFLOG)) @@ -321,7 +316,6 @@ $(eval $(call nf_add,EBTABLES_IP4,CONFIG_BRIDGE_EBT_SNAT, $(P_EBT)ebt_snat)) # watchers $(eval $(call nf_add,EBTABLES_WATCHERS,CONFIG_BRIDGE_EBT_LOG, $(P_EBT)ebt_log)) -$(eval $(call nf_add,EBTABLES_WATCHERS,CONFIG_BRIDGE_EBT_ULOG, $(P_EBT)ebt_ulog)) $(eval $(call nf_add,EBTABLES_WATCHERS,CONFIG_BRIDGE_EBT_NFLOG, $(P_EBT)ebt_nflog)) $(eval $(call nf_add,EBTABLES_WATCHERS,CONFIG_BRIDGE_EBT_NFQUEUE, $(P_EBT)ebt_nfqueue)) @@ -393,7 +387,6 @@ IPT_BUILTIN += $(IPT_NAT6-y) IPT_BUILTIN += $(IPT_NAT_EXTRA-y) IPT_BUILTIN += $(NF_NATHELPER-y) IPT_BUILTIN += $(NF_NATHELPER_EXTRA-y) -IPT_BUILTIN += $(IPT_ULOG-y) IPT_BUILTIN += $(IPT_TPROXY-y) IPT_BUILTIN += $(NFNETLINK-y) IPT_BUILTIN += $(NFNETLINK_LOG-y) diff --git a/include/nls.mk b/include/nls.mk index 0370a9bd3..f054d2bb6 100644 --- a/include/nls.mk +++ b/include/nls.mk @@ -9,13 +9,13 @@ ifeq ($(CONFIG_BUILD_NLS),y) INTL_PREFIX:=$(STAGING_DIR)/usr/lib/libintl-full INTL_FULL:=1 - + CMAKE_OPTIONS += -DCMAKE_PREFIX_PATH="$(ICONV_PREFIX);$(INTL_PREFIX)" else ICONV_PREFIX:= ICONV_FULL:= - INTL_PREFIX:=$ + INTL_PREFIX:= INTL_FULL:= endif diff --git a/include/package-defaults.mk b/include/package-defaults.mk index 3ee3a965f..72f88b9bb 100644 --- a/include/package-defaults.mk +++ b/include/package-defaults.mk @@ -2,7 +2,7 @@ # # Copyright (C) 2006-2020 OpenWrt.org -PKG_DEFAULT_DEPENDS = +libc +USE_GLIBC:librt +USE_GLIBC:libpthread +PKG_DEFAULT_DEPENDS = +libc ifneq ($(PKG_NAME),toolchain) PKG_FIXUP_DEPENDS = $(if $(filter kmod-%,$(1)),$(2),$(PKG_DEFAULT_DEPENDS) $(filter-out $(PKG_DEFAULT_DEPENDS),$(2))) diff --git a/include/target.mk b/include/target.mk index f9c2a9eed..2a138784c 100644 --- a/include/target.mk +++ b/include/target.mk @@ -233,6 +233,7 @@ ifeq ($(DUMP),1) ifeq ($(ARCH),powerpc) CPU_CFLAGS_603e:=-mcpu=603e CPU_CFLAGS_8540:=-mcpu=8540 + CPU_CFLAGS_8548:=-mcpu=8548 CPU_CFLAGS_405:=-mcpu=405 CPU_CFLAGS_440:=-mcpu=440 CPU_CFLAGS_464fp:=-mcpu=464fp diff --git a/include/trusted-firmware-a.mk b/include/trusted-firmware-a.mk index 46fc52b15..082ada269 100644 --- a/include/trusted-firmware-a.mk +++ b/include/trusted-firmware-a.mk @@ -1,5 +1,5 @@ PKG_NAME ?= trusted-firmware-a -PKG_CPE_ID ?= cpe:/a:arm:arm_trusted_firmware +PKG_CPE_ID ?= cpe:/a:arm:trusted_firmware-a ifndef PKG_SOURCE_PROTO PKG_SOURCE = trusted-firmware-a-$(PKG_VERSION).tar.gz @@ -81,6 +81,7 @@ define Build/Compile/Trusted-Firmware-A $(if $(DTC),DTC="$(DTC)") \ PLAT=$(PLAT) \ BUILD_STRING="OpenWrt v$(PKG_VERSION)-$(PKG_RELEASE) ($(VARIANT))" \ + $(if $(CONFIG_BINUTILS_VERSION_2_39),LDFLAGS="-no-warn-rwx-segments") \ $(TFA_MAKE_FLAGS) endef diff --git a/include/uclibc++.mk b/include/uclibc++.mk index a1a61f26d..10f8d98e1 100644 --- a/include/uclibc++.mk +++ b/include/uclibc++.mk @@ -1,16 +1,2 @@ -ifndef DUMP - ifdef __package_mk - $(error uclibc++.mk must be included before package.mk) - endif -endif - -PKG_PREPARED_DEPENDS += CONFIG_USE_UCLIBCXX -CXX_DEPENDS = +USE_UCLIBCXX:uclibcxx +USE_LIBSTDCXX:libstdcpp - -ifneq ($(CONFIG_USE_UCLIBCXX),) - ifneq ($(CONFIG_CCACHE),) - TARGET_CXX_NOCACHE=g++-uc - else - TARGET_CXX=g++-uc - endif -endif +$(warn uclibc++.mk is deprecated. Please remove it and CXX_DEPENDS) +CXX_DEPENDS = +libstdcpp diff --git a/package/kernel/bcm27xx-gpu-fw/Makefile b/package/kernel/bcm27xx-gpu-fw/Makefile index d34a48d11..b3323c8b2 100644 --- a/package/kernel/bcm27xx-gpu-fw/Makefile +++ b/package/kernel/bcm27xx-gpu-fw/Makefile @@ -2,8 +2,8 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=bcm27xx-gpu-fw -PKG_VERSION:=2021-02-16 -PKG_RELEASE:=ba6259246c702b04ea56ff1034325e476d460ae8 +PKG_VERSION:=2022-05-16 +PKG_RELEASE:=3673be308132de102fdff491d1333d9d0f823557 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)/rpi-firmware-$(PKG_RELEASE) @@ -26,7 +26,7 @@ define Download/bootcode_bin FILE:=$(RPI_FIRMWARE_FILE)-bootcode.bin URL:=$(RPI_FIRMWARE_URL) URL_FILE:=bootcode.bin - HASH:=92fd15eb2468187b69d15a9482d7e8cee3704993c53bb5ba55afe550723c5975 + HASH:=69309823da13dc96b89e3d82b44f820e4f84efa79d207adad2c8784559794f03 endef $(eval $(call Download,bootcode_bin)) @@ -34,7 +34,7 @@ define Download/fixup_dat FILE:=$(RPI_FIRMWARE_FILE)-fixup.dat URL:=$(RPI_FIRMWARE_URL) URL_FILE:=fixup.dat - HASH:=3daaf175decee44347fb97ece7738edf230b6fe3a86a8f521652e0052d5b3d6a + HASH:=921f56c62ad1995addb984b156c869202dc5d46bbe9ebcbd02c20f0def9058e3 endef $(eval $(call Download,fixup_dat)) @@ -42,7 +42,7 @@ define Download/fixup_cd_dat FILE:=$(RPI_FIRMWARE_FILE)-fixup_cd.dat URL:=$(RPI_FIRMWARE_URL) URL_FILE:=fixup_cd.dat - HASH:=399b10509877cc7cbbaae25757ff44ee9f666931dd5c0996b48d170735a668b0 + HASH:=83a985aa0d73844786f3b3bf674826c520212f6f72fc6a890f2ebb5f87de5d8c endef $(eval $(call Download,fixup_cd_dat)) @@ -50,7 +50,7 @@ define Download/fixup_x_dat FILE:=$(RPI_FIRMWARE_FILE)-fixup_x.dat URL:=$(RPI_FIRMWARE_URL) URL_FILE:=fixup_x.dat - HASH:=3c2a71f349bbc97bc3d9f7592bdd3f06d3d67e1ccd581cbdbb91b67a16304d76 + HASH:=8b00b00678adafe01e087240d156dbc87822e745b269be4f282596b69265cd1e endef $(eval $(call Download,fixup_x_dat)) @@ -58,7 +58,7 @@ define Download/fixup4_dat FILE:=$(RPI_FIRMWARE_FILE)-fixup4.dat URL:=$(RPI_FIRMWARE_URL) URL_FILE:=fixup4.dat - HASH:=68e9112ac7907af51cbf7f458d241e6136af1be4e968909e34cbffb70f9536b4 + HASH:=ef2b5d2a0a95ca48e00a1ce78b7650ee9e947cc1c588704c8ae30c1623122e2f endef $(eval $(call Download,fixup4_dat)) @@ -66,7 +66,7 @@ define Download/fixup4cd_dat FILE:=$(RPI_FIRMWARE_FILE)-fixup4cd.dat URL:=$(RPI_FIRMWARE_URL) URL_FILE:=fixup4cd.dat - HASH:=399b10509877cc7cbbaae25757ff44ee9f666931dd5c0996b48d170735a668b0 + HASH:=83a985aa0d73844786f3b3bf674826c520212f6f72fc6a890f2ebb5f87de5d8c endef $(eval $(call Download,fixup4cd_dat)) @@ -74,7 +74,7 @@ define Download/fixup4x_dat FILE:=$(RPI_FIRMWARE_FILE)-fixup4x.dat URL:=$(RPI_FIRMWARE_URL) URL_FILE:=fixup4x.dat - HASH:=62c0ff21c06a28c24fc537bd1d23625b3452170fbb9fbd950b67a393929c2768 + HASH:=a6c4e30ada5a00fe7de83c460638ca824647651bb4a3644b8c65d7ba1d9f2d2b endef $(eval $(call Download,fixup4x_dat)) @@ -82,7 +82,7 @@ define Download/start_elf FILE:=$(RPI_FIRMWARE_FILE)-start.elf URL:=$(RPI_FIRMWARE_URL) URL_FILE:=start.elf - HASH:=3cc30fc07a6ad99bdd14e6319ed84b6c8813e8cb08bc5fff488c33abb163f746 + HASH:=5455c148f4b8b04c553809bd22b995ee49ba5279ca3848df8bde6f80a388f7e0 endef $(eval $(call Download,start_elf)) @@ -90,7 +90,7 @@ define Download/start_cd_elf FILE:=$(RPI_FIRMWARE_FILE)-start_cd.elf URL:=$(RPI_FIRMWARE_URL) URL_FILE:=start_cd.elf - HASH:=a4ae5a07b036bd82136373f2ce8a9ad01e41938884568b57c53e4be4c08d0dda + HASH:=168c0a9178d5a3b4bd89ef770826a85b4ea3132560ba3600c212c0cec4c575c6 endef $(eval $(call Download,start_cd_elf)) @@ -98,7 +98,7 @@ define Download/start_x_elf FILE:=$(RPI_FIRMWARE_FILE)-start_x.elf URL:=$(RPI_FIRMWARE_URL) URL_FILE:=start_x.elf - HASH:=b566fc8bc4cd1699f40fc73aa72910915421764933f2f2a7ba517b6b14339d09 + HASH:=30c6a7f32a25185053ca3ca9e4bcfe932246ed42a1b7c37f8803209f93d86404 endef $(eval $(call Download,start_x_elf)) @@ -106,7 +106,7 @@ define Download/start4_elf FILE:=$(RPI_FIRMWARE_FILE)-start4.elf URL:=$(RPI_FIRMWARE_URL) URL_FILE:=start4.elf - HASH:=abafb4d39c2708389e1421443fdd5e8a86e03bef6ad5282c0b5836587860cc5c + HASH:=be8bbff41dba2749b7b0e812f0a9d87a9122d18508f7b5ff3cd20f303d15bc07 endef $(eval $(call Download,start4_elf)) @@ -114,7 +114,7 @@ define Download/start4cd_elf FILE:=$(RPI_FIRMWARE_FILE)-start4cd.elf URL:=$(RPI_FIRMWARE_URL) URL_FILE:=start4cd.elf - HASH:=6df423f4fa82c58efef6db1cf20c4fcbd92465a7fe91f40548c8534c1b5ef7fd + HASH:=000372e9cf6815ade595948dbd6328665f2a535eeee44e74b0ec8e56b6fbbf90 endef $(eval $(call Download,start4cd_elf)) @@ -122,7 +122,7 @@ define Download/start4x_elf FILE:=$(RPI_FIRMWARE_FILE)-start4x.elf URL:=$(RPI_FIRMWARE_URL) URL_FILE:=start4x.elf - HASH:=4060e9fedfa99ff91549c8f4324a18417db785d99054ac7fe7d1b5dd5ef232f1 + HASH:=48895858f7936570dfab44c67bdcb0357ac8fcd630162c36ac9ed8f2de85c038 endef $(eval $(call Download,start4x_elf)) diff --git a/package/kernel/bcm63xx-cfe/Makefile b/package/kernel/bcm63xx-cfe/Makefile index 568348e85..a8399ce11 100644 --- a/package/kernel/bcm63xx-cfe/Makefile +++ b/package/kernel/bcm63xx-cfe/Makefile @@ -2,13 +2,13 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=bcm63xx-cfe -PKG_RELEASE:=2 +PKG_RELEASE:=1 PKG_SOURCE_URL:=https://github.com/openwrt/bcm63xx-cfe.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2021-03-05 -PKG_SOURCE_VERSION:=d03501629fc8b1ba8f9b0961d543c256a3d0098f -PKG_MIRROR_HASH:=b32a6f68d59c8f4534def7ec2568ad7da7a612a605b9406328309c78115ee88d +PKG_SOURCE_DATE:=2021-06-22 +PKG_SOURCE_VERSION:=e5050f37150b34deb547b50feccd0e7439cb5bd7 +PKG_MIRROR_HASH:=85fed9f4bdf23cf7d33a02f549ffe9073666890f786d5ffa484c0368552b75ae PKG_FLAGS:=nonshared diff --git a/package/kernel/broadcom-wl/Makefile b/package/kernel/broadcom-wl/Makefile index 7188c4900..7eee86db8 100644 --- a/package/kernel/broadcom-wl/Makefile +++ b/package/kernel/broadcom-wl/Makefile @@ -99,8 +99,7 @@ define Package/nas/description proprietary Broadcom wl driver. endef -MAKE_KMOD := $(MAKE) -C "$(LINUX_DIR)" \ - $(KERNEL_MAKE_FLAGS) \ +MAKE_KMOD := $(KERNEL_MAKE) \ PATH="$(TARGET_PATH)" \ M="$(PKG_BUILD_DIR)/kmod" \ diff --git a/package/kernel/gpio-button-hotplug/Makefile b/package/kernel/gpio-button-hotplug/Makefile index 09f9c00e9..7ca6195a0 100644 --- a/package/kernel/gpio-button-hotplug/Makefile +++ b/package/kernel/gpio-button-hotplug/Makefile @@ -32,14 +32,8 @@ define KernelPackage/gpio-button-hotplug/description an overkill for OpenWrt simple needs. endef -MAKE_OPTS:= \ - $(KERNEL_MAKE_FLAGS) \ - M="$(PKG_BUILD_DIR)" - define Build/Compile - $(MAKE) -C "$(LINUX_DIR)" \ - $(MAKE_OPTS) \ - modules + $(KERNEL_MAKE) M="$(PKG_BUILD_DIR)" modules endef $(eval $(call KernelPackage,gpio-button-hotplug)) diff --git a/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c b/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c index 9575c6245..f086c8217 100644 --- a/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c +++ b/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c @@ -107,7 +107,7 @@ static struct bh_map button_map[] = { static __printf(3, 4) int bh_event_add_var(struct bh_event *event, int argv, const char *format, ...) { - static char buf[128]; + char buf[128]; char *s; va_list args; int len; diff --git a/package/kernel/gpio-nct5104d/Makefile b/package/kernel/gpio-nct5104d/Makefile index e85639c94..7f9a9fd2c 100644 --- a/package/kernel/gpio-nct5104d/Makefile +++ b/package/kernel/gpio-nct5104d/Makefile @@ -29,22 +29,9 @@ define KernelPackage/gpio-nct5104d/description Support for GPIO functionality of NCT5104D super I/O chip. endef -EXTRA_KCONFIG:= \ - CONFIG_GPIO_NCT5104D=m - -EXTRA_CFLAGS:= \ - $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(EXTRA_KCONFIG)))) \ - $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(EXTRA_KCONFIG)))) \ - -MAKE_OPTS:= \ - $(KERNEL_MAKE_FLAGS) \ - M="$(PKG_BUILD_DIR)" \ - EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ - $(EXTRA_KCONFIG) - define Build/Compile - $(MAKE) -C "$(LINUX_DIR)" \ - $(MAKE_OPTS) \ + $(KERNEL_MAKE) \ + M="$(PKG_BUILD_DIR)" \ modules endef diff --git a/package/kernel/gpio-nct5104d/src/Kconfig b/package/kernel/gpio-nct5104d/src/Kconfig deleted file mode 100644 index cf658e29c..000000000 --- a/package/kernel/gpio-nct5104d/src/Kconfig +++ /dev/null @@ -1,5 +0,0 @@ -config GPIO_NCT5104D - tristate "NCT5104D GPIO support" - depends on GENERIC_GPIO - help - Say yes here to support GPIO functionality of NCT5104D super I/O chip diff --git a/package/kernel/gpio-nct5104d/src/Makefile b/package/kernel/gpio-nct5104d/src/Makefile index 6f0375a34..9845c68c3 100644 --- a/package/kernel/gpio-nct5104d/src/Makefile +++ b/package/kernel/gpio-nct5104d/src/Makefile @@ -1 +1 @@ -obj-${CONFIG_GPIO_NCT5104D} += gpio-nct5104d.o +obj-m += gpio-nct5104d.o diff --git a/package/kernel/hwmon-gsc/Makefile b/package/kernel/hwmon-gsc/Makefile index 34c33dc58..cd7d4efb1 100644 --- a/package/kernel/hwmon-gsc/Makefile +++ b/package/kernel/hwmon-gsc/Makefile @@ -19,8 +19,7 @@ define KernelPackage/hwmon-gsc/description endef define Build/Compile - $(MAKE) -C "$(LINUX_DIR)" \ - $(KERNEL_MAKE_FLAGS) \ + $(KERNEL_MAKE) \ M="$(PKG_BUILD_DIR)" \ EXTRA_CFLAGS="$(BUILDFLAGS)" \ modules diff --git a/package/kernel/leds-ws2812b/Makefile b/package/kernel/leds-ws2812b/Makefile new file mode 100644 index 000000000..453d2590f --- /dev/null +++ b/package/kernel/leds-ws2812b/Makefile @@ -0,0 +1,34 @@ +# +# Copyright (C) 2008-2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=leds-ws2812b +PKG_RELEASE:=1 +PKG_LICENSE:=GPL-2.0 + +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/leds-ws2812b + SUBMENU:=LED modules + TITLE:=Worldsemi WS2812B (NeoPixel) LED support + FILES:= \ + $(PKG_BUILD_DIR)/leds-ws2812b.ko + AUTOLOAD:=$(call AutoProbe,leds-ws2812b,1) + DEPENDS:=@TARGET_mediatek_filogic +endef + +define KernelPackage/leds-ws2812b/description + LED support for driving WS2812B (NeoPixel) using SPI MOSI. +endef + +define Build/Compile + $(KERNEL_MAKE) M="$(PKG_BUILD_DIR)" modules +endef + +$(eval $(call KernelPackage,leds-ws2812b)) diff --git a/package/kernel/leds-ws2812b/src/Makefile b/package/kernel/leds-ws2812b/src/Makefile new file mode 100644 index 000000000..718a9f708 --- /dev/null +++ b/package/kernel/leds-ws2812b/src/Makefile @@ -0,0 +1 @@ +obj-m := leds-ws2812b.o diff --git a/package/kernel/leds-ws2812b/src/leds-ws2812b.c b/package/kernel/leds-ws2812b/src/leds-ws2812b.c new file mode 100644 index 000000000..b0d13f524 --- /dev/null +++ b/package/kernel/leds-ws2812b/src/leds-ws2812b.c @@ -0,0 +1,233 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * WorldSemi WS2812B individually-addressable LED driver using SPI + * + * Copyright 2022 Chuanhong Guo + * + * This driver simulates WS2812B protocol using SPI MOSI pin. A one pulse + * is transferred as 3'b110 and a zero pulse is 3'b100. For this driver to + * work properly, the SPI frequency should be 2.105MHz~2.85MHz and it needs + * to transfer all the bytes continuously. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define WS2812B_BYTES_PER_COLOR 3 +#define WS2812B_NUM_COLORS 3 +/* A continuous 0 for 50us+ as the 'reset' signal */ +#define WS2812B_RESET_LEN 18 + +struct ws2812b_led { + struct led_classdev_mc mc_cdev; + struct mc_subled subled[WS2812B_NUM_COLORS]; + int cascade; +}; + +struct ws2812b_priv { + struct led_classdev ldev; + struct spi_device *spi; + struct mutex mutex; + int num_leds; + size_t data_len; + u8 *data_buf; + struct ws2812b_led leds[]; +}; + +/** + * ws2812b_set_byte - convert a byte of data to 3-byte SPI data for pulses + * @priv: pointer to the private data structure + * @offset: offset of the target byte in the data stream + * @val: 1-byte data to be set + * + * WS2812B receives a stream of bytes from DI, takes the first 3 byte as LED + * brightness and pases the rest to the next LED through the DO pin. + * This function assembles a single byte of data to the LED: + * A bit is represented with a pulse of specific length. A long pulse is a 1 + * and a short pulse is a 0. + * SPI transfers data continuously, MSB first. We can send 3'b100 to create a + * 0 pulse and 3'b110 for a 1 pulse. In this way, a byte of data takes up 3 + * bytes in a SPI transfer: + * 1x0 1x0 1x0 1x0 1x0 1x0 1x0 1x0 + * Let's rearrange it in 8 bits: + * 1x01x01x 01x01x01 x01x01x0 + * The higher 3 bits, middle 2 bits and lower 3 bits are represented with the + * 1st, 2nd and 3rd byte in the SPI transfer respectively. + * There are only 8 combinations for 3 bits and 4 for 2 bits, so we can create + * a lookup table for the 3 bytes. + * e.g. For 0x6b -> 2'b01101011: + * Bit 7-5: 3'b011 -> 10011011 -> 0x9b + * Bit 4-3: 2'b01 -> 01001101 -> 0x4d + * Bit 2-0: 3'b011 -> 00110110 -> 0x36 + */ +static void ws2812b_set_byte(struct ws2812b_priv *priv, size_t offset, u8 val) +{ + /* The lookup table for Bit 7-5 4-3 2-0 */ + const u8 h3b[] = { 0x92, 0x93, 0x9a, 0x9b, 0xd2, 0xd3, 0xda, 0xdb }; + const u8 m2b[] = { 0x49, 0x4d, 0x69, 0x6d }; + const u8 l3b[] = { 0x24, 0x26, 0x34, 0x36, 0xa4, 0xa6, 0xb4, 0xb6 }; + u8 *p = priv->data_buf + WS2812B_RESET_LEN + (offset * WS2812B_BYTES_PER_COLOR); + + p[0] = h3b[val >> 5]; /* Bit 7-5 */ + p[1] = m2b[(val >> 3) & 0x3]; /* Bit 4-3 */ + p[2] = l3b[val & 0x7]; /* Bit 2-0 */ +} + +static int ws2812b_set(struct led_classdev *cdev, + enum led_brightness brightness) +{ + struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev); + struct ws2812b_led *led = + container_of(mc_cdev, struct ws2812b_led, mc_cdev); + struct ws2812b_priv *priv = dev_get_drvdata(cdev->dev->parent); + int ret; + int i; + + led_mc_calc_color_components(mc_cdev, brightness); + + mutex_lock(&priv->mutex); + for (i = 0; i < WS2812B_NUM_COLORS; i++) + ws2812b_set_byte(priv, led->cascade * WS2812B_NUM_COLORS + i, + led->subled[i].brightness); + ret = spi_write(priv->spi, priv->data_buf, priv->data_len); + mutex_unlock(&priv->mutex); + + return ret; +} + +static int ws2812b_probe(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + int cur_led = 0; + struct ws2812b_priv *priv; + struct fwnode_handle *led_node; + int num_leds, i, cnt, ret; + + num_leds = device_get_child_node_count(dev); + + priv = devm_kzalloc(dev, struct_size(priv, leds, num_leds), GFP_KERNEL); + if (!priv) + return -ENOMEM; + priv->data_len = + num_leds * WS2812B_BYTES_PER_COLOR * WS2812B_NUM_COLORS + + WS2812B_RESET_LEN; + priv->data_buf = kzalloc(priv->data_len, GFP_KERNEL); + if (!priv->data_buf) + return -ENOMEM; + + for (i = 0; i < num_leds * WS2812B_NUM_COLORS; i++) + ws2812b_set_byte(priv, i, 0); + + mutex_init(&priv->mutex); + priv->num_leds = num_leds; + priv->spi = spi; + + device_for_each_child_node(dev, led_node) { + struct led_init_data init_data = { + .fwnode = led_node, + }; + /* WS2812B LEDs usually come with GRB color */ + u32 color_idx[WS2812B_NUM_COLORS] = { + LED_COLOR_ID_GREEN, + LED_COLOR_ID_RED, + LED_COLOR_ID_BLUE, + }; + u32 cascade; + + ret = fwnode_property_read_u32(led_node, "reg", &cascade); + if (ret) { + dev_err(dev, "failed to obtain numerical LED index for %s", + fwnode_get_name(led_node)); + goto ERR_UNREG_LEDS; + } + if (cascade >= num_leds) { + dev_err(dev, "LED index of %s is larger than the number of LEDs.", + fwnode_get_name(led_node)); + ret = -EINVAL; + goto ERR_UNREG_LEDS; + } + + cnt = fwnode_property_count_u32(led_node, "color-index"); + if (cnt > 0 && cnt <= WS2812B_NUM_COLORS) + fwnode_property_read_u32_array(led_node, "color-index", + color_idx, (size_t)cnt); + + priv->leds[cur_led].mc_cdev.subled_info = + priv->leds[cur_led].subled; + priv->leds[cur_led].mc_cdev.num_colors = WS2812B_NUM_COLORS; + priv->leds[cur_led].mc_cdev.led_cdev.max_brightness = 255; + priv->leds[cur_led].mc_cdev.led_cdev.brightness_set_blocking = ws2812b_set; + + for (i = 0; i < WS2812B_NUM_COLORS; i++) { + priv->leds[cur_led].subled[i].color_index = color_idx[i]; + priv->leds[cur_led].subled[i].intensity = 255; + } + + priv->leds[cur_led].cascade = cascade; + + ret = led_classdev_multicolor_register_ext( + dev, &priv->leds[cur_led].mc_cdev, &init_data); + if (ret) { + dev_err(dev, "registration of %s failed.", + fwnode_get_name(led_node)); + goto ERR_UNREG_LEDS; + } + cur_led++; + } + + spi_set_drvdata(spi, priv); + + return 0; +ERR_UNREG_LEDS: + for (; cur_led >= 0; cur_led--) + led_classdev_multicolor_unregister(&priv->leds[cur_led].mc_cdev); + mutex_destroy(&priv->mutex); + kfree(priv->data_buf); + return ret; +} + +static int ws2812b_remove(struct spi_device *spi) +{ + struct ws2812b_priv *priv = spi_get_drvdata(spi); + int cur_led; + + for (cur_led = priv->num_leds - 1; cur_led >= 0; cur_led--) + led_classdev_multicolor_unregister(&priv->leds[cur_led].mc_cdev); + kfree(priv->data_buf); + mutex_destroy(&priv->mutex); + + return 0; +} + +static const struct spi_device_id ws2812b_spi_ids[] = { + { "ws2812b" }, + {}, +}; +MODULE_DEVICE_TABLE(spi, ws2812b_spi_ids); + +static const struct of_device_id ws2812b_dt_ids[] = { + { .compatible = "worldsemi,ws2812b" }, + {}, +}; +MODULE_DEVICE_TABLE(of, ws2812b_dt_ids); + +static struct spi_driver ws2812b_driver = { + .probe = ws2812b_probe, + .remove = ws2812b_remove, + .id_table = ws2812b_spi_ids, + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = ws2812b_dt_ids, + }, +}; + +module_spi_driver(ws2812b_driver); + +MODULE_AUTHOR("Chuanhong Guo "); +MODULE_DESCRIPTION("WS2812B LED driver using SPI"); +MODULE_LICENSE("GPL"); diff --git a/package/kernel/mtk-eip93/Config.in b/package/kernel/mtk-eip93/Config.in new file mode 100644 index 000000000..07e001d01 --- /dev/null +++ b/package/kernel/mtk-eip93/Config.in @@ -0,0 +1,17 @@ +if PACKAGE_kmod-crypto-hw-eip93 + +config MTK_EIP93_GENERIC_SW_MAX_LEN + int "Max skcipher software fallback length" + default 256 + help + Max length of crypt request which + will fallback to software crypt of skcipher *except* AES-128. + +config MTK_EIP93_AES_128_SW_MAX_LEN + int "Max AES-128 skcipher software fallback length" + default 512 + help + Max length of crypt request which + will fallback to software crypt of AES-128 skcipher. + +endif diff --git a/package/kernel/mtk-eip93/Makefile b/package/kernel/mtk-eip93/Makefile new file mode 100644 index 000000000..e117e5da5 --- /dev/null +++ b/package/kernel/mtk-eip93/Makefile @@ -0,0 +1,68 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=mtk-eip93 +PKG_RELEASE:=1 + +PKG_LICENSE:=GPLv2 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/vschagen/mtk-eip93.git +PKG_SOURCE_VERSION:=ca08387bf8352652129019bb19e2423ab313d5cb +PKG_MIRROR_HASH:=4505ee2a175a6cf77a1a3b4fa7bf188da8f8b47894e5afa62c8cb008fbfa15ed + +MAKE_PATH:=crypto/mtk-eip93 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/crypto-hw-eip93 + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Cryptographic API modules + DEPENDS:= \ + @TARGET_ramips_mt7621 \ + +kmod-crypto-authenc \ + +kmod-crypto-des \ + +kmod-crypto-md5 \ + +kmod-crypto-sha1 \ + +kmod-crypto-sha256 + TITLE:=MTK EIP93 crypto module. + FILES:=$(PKG_BUILD_DIR)/$(MAKE_PATH)/crypto-hw-eip93.ko + AUTOLOAD:=$(call AutoProbe,crypto-hw-eip93) + MENU:=1 +endef + +define KernelPackage/crypto-hw-eip93/description +Kernel module to enable EIP-93 Crypto engine as found +in the Mediatek MT7621 SoC. +It enables DES/3DES/AES ECB/CBC/CTR and +IPSEC offload with authenc(hmac(sha1/sha256), aes/cbc/rfc3686) +endef + +define KernelPackage/crypto-hw-eip93/config + source "$(SOURCE)/Config.in" +endef + +EIP93_EXTRA_CFLAGS:= \ + -D CONFIG_CRYPTO_DEV_EIP93_SKCIPHER=1 \ + -D CONFIG_CRYPTO_DEV_EIP93_HMAC=1 \ + -D CONFIG_CRYPTO_DEV_EIP93_AES=1 \ + -D CONFIG_CRYPTO_DEV_EIP93_DES=1 \ + -D CONFIG_CRYPTO_DEV_EIP93_AEAD=1 \ + -D CONFIG_MTK_EIP93_GENERIC_SW_MAX_LEN=$(CONFIG_MTK_EIP93_GENERIC_SW_MAX_LEN) \ + -D CONFIG_MTK_EIP93_AES_128_SW_MAX_LEN=$(CONFIG_MTK_EIP93_AES_128_SW_MAX_LEN) +EIP93_MAKE_FLAGS:= \ + EXTRA_CFLAGS="$(EIP93_EXTRA_CFLAGS)" \ + CONFIG_CRYPTO_DEV_EIP93=m \ + CONFIG_CRYPTO_DEV_EIP93_SKCIPHER=y \ + CONFIG_CRYPTO_DEV_EIP93_AEAD=y + +define Build/Compile + $(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \ + $(KERNEL_MAKE_FLAGS) \ + $(EIP93_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)/$(MAKE_PATH)" \ + modules +endef + +$(eval $(call KernelPackage,crypto-hw-eip93)) diff --git a/package/kernel/mtk-eip93/patches/002-crypto-use-AES-fallback-for-small-requests.patch b/package/kernel/mtk-eip93/patches/002-crypto-use-AES-fallback-for-small-requests.patch new file mode 100644 index 000000000..5e857aaba --- /dev/null +++ b/package/kernel/mtk-eip93/patches/002-crypto-use-AES-fallback-for-small-requests.patch @@ -0,0 +1,177 @@ +From f39ee05bedc68cf80e76c69692f87b96bf5a3b51 Mon Sep 17 00:00:00 2001 +From: Aviana Cruz +Date: Tue, 21 Jun 2022 10:47:10 +0800 +Subject: [PATCH] crypto: use AES fallback for small requests + +Signed-off-by: Aviana Cruz +--- + crypto/mtk-eip93/eip93-aead.c | 2 - + crypto/mtk-eip93/eip93-cipher.c | 66 ++++++++++++++++++++++++++++++--- + crypto/mtk-eip93/eip93-cipher.h | 3 ++ + 3 files changed, 63 insertions(+), 8 deletions(-) + +--- a/crypto/mtk-eip93/eip93-aead.c ++++ b/crypto/mtk-eip93/eip93-aead.c +@@ -77,8 +77,6 @@ static int mtk_aead_cra_init(struct cryp + u32 flags = tmpl->flags; + char *alg_base; + +- memset(ctx, 0, sizeof(*ctx)); +- + crypto_aead_set_reqsize(__crypto_aead_cast(tfm), + sizeof(struct mtk_cipher_reqctx)); + +--- a/crypto/mtk-eip93/eip93-cipher.c ++++ b/crypto/mtk-eip93/eip93-cipher.c +@@ -31,6 +31,13 @@ void mtk_skcipher_handle_result(struct c + skcipher_request_complete(req, err); + } + ++static inline bool mtk_skcipher_is_fallback(const struct crypto_tfm *tfm, ++ u32 flags) ++{ ++ return (tfm->__crt_alg->cra_flags & CRYPTO_ALG_NEED_FALLBACK) && ++ !IS_RFC3686(flags); ++} ++ + static int mtk_skcipher_send_req(struct crypto_async_request *async) + { + struct skcipher_request *req = skcipher_request_cast(async); +@@ -53,11 +60,21 @@ static int mtk_skcipher_cra_init(struct + struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(tfm); + struct mtk_alg_template *tmpl = container_of(tfm->__crt_alg, + struct mtk_alg_template, alg.skcipher.base); ++ bool fallback = mtk_skcipher_is_fallback(tfm, tmpl->flags); ++ ++ if (fallback) { ++ ctx->fallback = crypto_alloc_skcipher( ++ crypto_tfm_alg_name(tfm), 0, CRYPTO_ALG_NEED_FALLBACK); ++ if (IS_ERR(ctx->fallback)) ++ return PTR_ERR(ctx->fallback); ++ } + +- crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm), +- sizeof(struct mtk_cipher_reqctx)); ++ crypto_skcipher_set_reqsize( ++ __crypto_skcipher_cast(tfm), ++ sizeof(struct mtk_cipher_reqctx) + ++ (fallback ? crypto_skcipher_reqsize(ctx->fallback) : ++ 0)); + +- memset(ctx, 0, sizeof(*ctx)); + ctx->mtk = tmpl->mtk; + + ctx->sa_in = kzalloc(sizeof(struct saRecord_s), GFP_KERNEL); +@@ -86,6 +103,8 @@ static void mtk_skcipher_cra_exit(struct + sizeof(struct saRecord_s), DMA_TO_DEVICE); + kfree(ctx->sa_in); + kfree(ctx->sa_out); ++ ++ crypto_free_skcipher(ctx->fallback); + } + + static int mtk_skcipher_setkey(struct crypto_skcipher *ctfm, const u8 *key, +@@ -105,6 +124,8 @@ static int mtk_skcipher_setkey(struct cr + if (!key || !keylen) + return err; + ++ ctx->keylen = keylen; ++ + #if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES) + if (IS_RFC3686(flags)) { + if (len < CTR_RFC3686_NONCE_SIZE) +@@ -128,6 +149,14 @@ static int mtk_skcipher_setkey(struct cr + #if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES) + if (flags & MTK_ALG_AES) { + struct crypto_aes_ctx aes; ++ bool fallback = mtk_skcipher_is_fallback(tfm, flags); ++ ++ if (fallback && !IS_RFC3686(flags)) { ++ err = crypto_skcipher_setkey(ctx->fallback, key, ++ keylen); ++ if (err) ++ return err; ++ } + + ctx->blksize = AES_BLOCK_SIZE; + err = aes_expandkey(&aes, key, keylen); +@@ -160,16 +189,41 @@ static int mtk_skcipher_setkey(struct cr + return err; + } + +-static int mtk_skcipher_crypt(struct skcipher_request *req) ++static int mtk_skcipher_crypt(struct skcipher_request *req, bool encrypt) + { + struct mtk_cipher_reqctx *rctx = skcipher_request_ctx(req); + struct crypto_async_request *async = &req->base; + struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm); + struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); ++ bool fallback = mtk_skcipher_is_fallback(req->base.tfm, rctx->flags); + + if (!req->cryptlen) + return 0; + ++ /* ++ * ECB and CBC algorithms require message lengths to be ++ * multiples of block size. ++ */ ++ if (IS_ECB(rctx->flags) || IS_CBC(rctx->flags)) ++ if (!IS_ALIGNED(req->cryptlen, ++ crypto_skcipher_blocksize(skcipher))) ++ return -EINVAL; ++ ++ if (fallback && ++ req->cryptlen <= (AES_KEYSIZE_128 ? ++ CONFIG_MTK_EIP93_AES_128_SW_MAX_LEN : ++ CONFIG_MTK_EIP93_GENERIC_SW_MAX_LEN)) { ++ skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); ++ skcipher_request_set_callback(&rctx->fallback_req, ++ req->base.flags, ++ req->base.complete, ++ req->base.data); ++ skcipher_request_set_crypt(&rctx->fallback_req, req->src, ++ req->dst, req->cryptlen, req->iv); ++ return encrypt ? crypto_skcipher_encrypt(&rctx->fallback_req) : ++ crypto_skcipher_decrypt(&rctx->fallback_req); ++ } ++ + rctx->assoclen = 0; + rctx->textsize = req->cryptlen; + rctx->authsize = 0; +@@ -195,7 +249,7 @@ static int mtk_skcipher_encrypt(struct s + rctx->flags |= MTK_ENCRYPT; + rctx->saRecord_base = ctx->sa_base_out; + +- return mtk_skcipher_crypt(req); ++ return mtk_skcipher_crypt(req, true); + } + + static int mtk_skcipher_decrypt(struct skcipher_request *req) +@@ -209,7 +263,7 @@ static int mtk_skcipher_decrypt(struct s + rctx->flags |= MTK_DECRYPT; + rctx->saRecord_base = ctx->sa_base_in; + +- return mtk_skcipher_crypt(req); ++ return mtk_skcipher_crypt(req, false); + } + + /* Available algorithms in this module */ +--- a/crypto/mtk-eip93/eip93-cipher.h ++++ b/crypto/mtk-eip93/eip93-cipher.h +@@ -24,6 +24,8 @@ struct mtk_crypto_ctx { + bool in_first; + bool out_first; + struct crypto_shash *shash; ++ unsigned int keylen; ++ struct crypto_skcipher *fallback; + }; + + struct mtk_cipher_reqctx { +@@ -45,6 +47,7 @@ struct mtk_cipher_reqctx { + struct saState_s *saState_ctr; + dma_addr_t saState_base_ctr; + uint32_t saState_ctr_idx; ++ struct skcipher_request fallback_req; // keep at the end + }; + + int check_valid_request(struct mtk_cipher_reqctx *rctx); diff --git a/package/kernel/mtk-eip93/patches/100-fix-build-on-kernel-5.4.patch b/package/kernel/mtk-eip93/patches/100-fix-build-on-kernel-5.4.patch new file mode 100644 index 000000000..8f9e0b93b --- /dev/null +++ b/package/kernel/mtk-eip93/patches/100-fix-build-on-kernel-5.4.patch @@ -0,0 +1,48 @@ +--- a/crypto/mtk-eip93/eip93-aead.c ++++ b/crypto/mtk-eip93/eip93-aead.c +@@ -13,8 +13,6 @@ + #include + #include + #include +-#include +-#include + + #if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES) + #include +@@ -22,6 +20,14 @@ + + #include + #include ++#include ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) ++#include ++#else ++#include ++#include ++#endif + + #include "eip93-aead.h" + #include "eip93-cipher.h" +--- a/crypto/mtk-eip93/eip93-common.c ++++ b/crypto/mtk-eip93/eip93-common.c +@@ -8,11 +8,17 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include ++#include ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) ++#include ++#else ++#include ++#include ++#endif + + #include "eip93-cipher.h" + #include "eip93-common.h" diff --git a/package/kernel/mwlwifi/Makefile b/package/kernel/mwlwifi/Makefile index a28a776fb..c0af474c7 100644 --- a/package/kernel/mwlwifi/Makefile +++ b/package/kernel/mwlwifi/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mwlwifi -PKG_RELEASE=1 +PKG_RELEASE=3 PKG_LICENSE:=ISC PKG_LICENSE_FILES:= @@ -29,7 +29,7 @@ include $(INCLUDE_DIR)/package.mk define KernelPackage/mwlwifi SUBMENU:=Wireless Drivers TITLE:=Marvell 88W8864/88W8897/88W8964/88W8997 wireless driver - DEPENDS:=+kmod-mac80211 +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11W_SUPPORT @PCI_SUPPORT @TARGET_mvebu + DEPENDS:=+kmod-mac80211 +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT @PCI_SUPPORT @TARGET_mvebu FILES:=$(PKG_BUILD_DIR)/mwlwifi.ko AUTOLOAD:=$(call AutoLoad,50,mwlwifi) endef @@ -44,8 +44,7 @@ NOSTDINC_FLAGS := \ -include backport/backport.h define Build/Compile - +$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \ - $(KERNEL_MAKE_FLAGS) \ + +$(KERNEL_MAKE) $(PKG_JOBS) \ M="$(PKG_BUILD_DIR)" \ NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \ modules diff --git a/package/kernel/mwlwifi/patches/002-disable-AMSDU.patch b/package/kernel/mwlwifi/patches/002-disable-AMSDU.patch deleted file mode 100644 index 3fd48ca57..000000000 --- a/package/kernel/mwlwifi/patches/002-disable-AMSDU.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/core.c -+++ b/core.c -@@ -982,7 +982,7 @@ struct ieee80211_hw *mwl_alloc_hw(int bu - priv->use_short_preamble = false; - priv->disable_2g = false; - priv->disable_5g = false; -- priv->tx_amsdu = true; -+ priv->tx_amsdu = false; - priv->hif.bus = bus_type; - priv->hif.ops = ops; - priv->hif.priv = (char *)priv + ALIGN(sizeof(*priv), NETDEV_ALIGN); diff --git a/package/kernel/mwlwifi/patches/002-mwlwifi-remove-MODULE_SUPPORTED_DEVICE.patch b/package/kernel/mwlwifi/patches/002-mwlwifi-remove-MODULE_SUPPORTED_DEVICE.patch new file mode 100644 index 000000000..23b4ef754 --- /dev/null +++ b/package/kernel/mwlwifi/patches/002-mwlwifi-remove-MODULE_SUPPORTED_DEVICE.patch @@ -0,0 +1,32 @@ +From 392f8e9d798acff3079e753dd881e272f6150d74 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Wed, 30 Mar 2022 19:32:38 +0200 +Subject: [PATCH] mwlwifi: remove MODULE_SUPPORTED_DEVICE + +Kernel 5.12 finally removed all MODULE_SUPPORTED_DEVICE references and +support for it as it was never actually implemented and was safe to +drop it completely. + +So, do the same in order to compile in 5.12 and newer. + +Signed-off-by: Robert Marko +--- + hif/pcie/pcie.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/hif/pcie/pcie.c ++++ b/hif/pcie/pcie.c +@@ -31,7 +31,6 @@ + #include "hif/pcie/rx_ndp.h" + + #define PCIE_DRV_DESC "Marvell Mac80211 Wireless PCIE Network Driver" +-#define PCIE_DEV_NAME "Marvell 802.11ac PCIE Adapter" + + #define MAX_WAIT_FW_COMPLETE_ITERATIONS 10000 + #define CHECK_BA_TRAFFIC_TIME 300 /* msec */ +@@ -1641,5 +1640,4 @@ MODULE_DESCRIPTION(PCIE_DRV_DESC); + MODULE_VERSION(PCIE_DRV_VERSION); + MODULE_AUTHOR("Marvell Semiconductor, Inc."); + MODULE_LICENSE("GPL v2"); +-MODULE_SUPPORTED_DEVICE(PCIE_DEV_NAME); + MODULE_DEVICE_TABLE(pci, pcie_id_tbl); diff --git a/package/kernel/mwlwifi/patches/003-mwlwifi-replace-get-set_fs-calls.patch b/package/kernel/mwlwifi/patches/003-mwlwifi-replace-get-set_fs-calls.patch new file mode 100644 index 000000000..725a41c9a --- /dev/null +++ b/package/kernel/mwlwifi/patches/003-mwlwifi-replace-get-set_fs-calls.patch @@ -0,0 +1,39 @@ +From 16e51cb83f9fa1717383c9d67f5531df7348347c Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Wed, 30 Mar 2022 19:51:56 +0200 +Subject: [PATCH] mwlwifi: replace get/set_fs() calls + +Since kernel 5.9 the get/set_fs() call implementation have started to get +dropped from individual architectures, ARM64 one got dropped in 5.11. + +Replace the get/set_fs() calls with force_uaccess_begin/end() to allow +compiling on newer kernels. +There is no need to add kernel version checks as the replacement functions +are available since kernel 5.9. + +Signed-off-by: Robert Marko +--- + hif/pcie/pcie.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/hif/pcie/pcie.c ++++ b/hif/pcie/pcie.c +@@ -1293,8 +1293,7 @@ static void pcie_bf_mimo_ctrl_decode(str + char *buf = &str_buf[0]; + mm_segment_t oldfs; + +- oldfs = get_fs(); +- set_fs(KERNEL_DS); ++ oldfs = force_uaccess_begin(); + + buf += sprintf(buf, "\nMAC: %pM\n", bf_mimo_ctrl->rec_mac); + buf += sprintf(buf, "SU_0_MU_1: %d\n", bf_mimo_ctrl->type); +@@ -1314,7 +1313,7 @@ static void pcie_bf_mimo_ctrl_decode(str + filename, (unsigned int)fp_data); + } + +- set_fs(oldfs); ++ force_uaccess_end(oldfs); + } + + static void pcie_process_account(struct ieee80211_hw *hw) diff --git a/package/kernel/mwlwifi/patches/004-mwlwifi-fix-PCIe-DT-node-null-pointer-dereference.patch b/package/kernel/mwlwifi/patches/004-mwlwifi-fix-PCIe-DT-node-null-pointer-dereference.patch new file mode 100644 index 000000000..9b9e49b66 --- /dev/null +++ b/package/kernel/mwlwifi/patches/004-mwlwifi-fix-PCIe-DT-node-null-pointer-dereference.patch @@ -0,0 +1,31 @@ +From 8e809b241695252e397bf0d7fc5f36e115c38831 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 5 Mar 2021 11:47:59 +0100 +Subject: [PATCH] mwlwifi: fix PCIe DT node null pointer dereference + +pci_bus_to_OF_node() used to get the PCI bus DT node +returns node if found or NULL if none is found. + +Since the return of pci_bus_to_OF_node() is not checked in +the DT node name print it will cause a null pointer +dereference and crash the kernel. + +So first check whether the node is not NULL and then print. + +Signed-off-by: Robert Marko +--- + hif/pcie/pcie.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/hif/pcie/pcie.c ++++ b/hif/pcie/pcie.c +@@ -570,7 +570,8 @@ static struct device_node *pcie_get_devi + struct device_node *dev_node; + + dev_node = pci_bus_to_OF_node(pcie_priv->pdev->bus); +- wiphy_info(priv->hw->wiphy, "device node: %s\n", dev_node->full_name); ++ if (dev_node) ++ wiphy_info(priv->hw->wiphy, "device node: %s\n", dev_node->full_name); + + return dev_node; + } diff --git a/package/kernel/nat46/Makefile b/package/kernel/nat46/Makefile index ef1a90ed8..2b131a9a7 100644 --- a/package/kernel/nat46/Makefile +++ b/package/kernel/nat46/Makefile @@ -3,11 +3,11 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=nat46 -PKG_MIRROR_HASH:=3b424241de42b96d47217decf6f9071153cd0c11651f1ee006700836c6660fe8 +PKG_MIRROR_HASH:=c26b8c60aa991a087011b8b6492e43a6749f0a5d9dc79ffcfd352da5fa20b78d PKG_SOURCE_URL:=https://github.com/ayourtch/nat46.git -PKG_SOURCE_DATE:=2021-05-17 +PKG_SOURCE_DATE:=2022-03-30 PKG_SOURCE_PROTO:=git -PKG_SOURCE_VERSION:=0d5860d63a8037e001e293091ebf6219cc2f9255 +PKG_SOURCE_VERSION:=95ca1c3b99376da2d0306919f2df4a8d3c9bb78b PKG_MAINTAINER:=Hans Dedecker PKG_LICENSE:=GPL-2.0 diff --git a/package/kernel/rtc-rv5c386a/Makefile b/package/kernel/rtc-rv5c386a/Makefile index 0cca78548..7c18942ff 100644 --- a/package/kernel/rtc-rv5c386a/Makefile +++ b/package/kernel/rtc-rv5c386a/Makefile @@ -22,8 +22,7 @@ define KernelPackage/rtc-rv5c386a endef define Build/Compile - $(MAKE) -C "$(LINUX_DIR)" \ - $(KERNEL_MAKE_FLAGS) \ + $(KERNEL_MAKE) \ M="$(PKG_BUILD_DIR)" \ EXTRA_CFLAGS="$(BUILDFLAGS)" \ modules diff --git a/package/kernel/rtl8812au-ac/Makefile b/package/kernel/rtl8812au-ac/Makefile deleted file mode 100644 index ee89067dd..000000000 --- a/package/kernel/rtl8812au-ac/Makefile +++ /dev/null @@ -1,79 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-only -# -# Copyright (C) 2020 stepheny -# -# -# Copyright (C) 2021-2022 ImmortalWrt.org - -include $(TOPDIR)/rules.mk - -PKG_NAME:=rtl8812au-ac -PKG_RELEASE:=$(AUTORELEASE) - -PKG_SOURCE_URL:=https://github.com/aircrack-ng/rtl8812au.git -PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2021-05-22 -PKG_SOURCE_VERSION:=0b87ed921a8682856aed5a3e68344b0087f3c93c -PKG_MIRROR_HASH:=f351622acacda52580d5983f5fa6130f625c80f9ee7500543ff8333d57ec3b74 - -PKG_LICENSE:=GPL-2.0 -PKG_LICENSE_FILES:=LICENSE -PKG_MAINTAINER:=Marty Jones - -PKG_BUILD_PARALLEL:=1 - -STAMP_CONFIGURED_DEPENDS := $(STAGING_DIR)/usr/include/mac80211-backport/backport/autoconf.h - -include $(INCLUDE_DIR)/kernel.mk -include $(INCLUDE_DIR)/package.mk - -define KernelPackage/rtl8812au-ac - SUBMENU:=Wireless Drivers - TITLE:=Realtek RTL8812AU/21AU wireless drivers - DEPENDS:=+kmod-cfg80211 +kmod-usb-core +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT - FILES:=$(PKG_BUILD_DIR)/rtl8812au.ko - AUTOLOAD:=$(call AutoProbe,rtl8812au) - CONFLICTS:=kmod-rtl8812au-ct -endef - -NOSTDINC_FLAGS = \ - -I$(PKG_BUILD_DIR) \ - -I$(PKG_BUILD_DIR)/include \ - -I$(STAGING_DIR)/usr/include/mac80211-backport \ - -I$(STAGING_DIR)/usr/include/mac80211-backport/uapi \ - -I$(STAGING_DIR)/usr/include/mac80211 \ - -I$(STAGING_DIR)/usr/include/mac80211/uapi \ - -include backport/autoconf.h \ - -include backport/backport.h - -EXTRA_KCONFIG:= \ - CONFIG_88XXAU=m \ - USER_MODULE_NAME=rtl8812au - -EXTRA_CFLAGS:= \ - -DRTW_SINGLE_WIPHY \ - -DRTW_USE_CFG80211_STA_EVENT \ - -DCONFIG_IOCTL_CFG80211 \ - -DCONFIG_CONCURRENT_MODE \ - -DBUILD_OPENWRT - -ifeq ($(CONFIG_BIG_ENDIAN),y) -EXTRA_CFLAGS += -DCONFIG_BIG_ENDIAN -else -EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -endif - -MAKE_OPTS:= \ - $(KERNEL_MAKE_FLAGS) \ - M="$(PKG_BUILD_DIR)" \ - NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \ - USER_EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ - $(EXTRA_KCONFIG) - -define Build/Compile - +$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \ - $(MAKE_OPTS) \ - modules -endef - -$(eval $(call KernelPackage,rtl8812au-ac)) diff --git a/package/kernel/rtl8812au-ac/patches/001-use-kernel-byteorder.patch b/package/kernel/rtl8812au-ac/patches/001-use-kernel-byteorder.patch deleted file mode 100644 index 187a6788e..000000000 --- a/package/kernel/rtl8812au-ac/patches/001-use-kernel-byteorder.patch +++ /dev/null @@ -1,15 +0,0 @@ -Fix compile problem when rtw_byteorder.h and asm/byteorder.h gets -included in addition for example indirectly, do not use realtek own copy -of the byteorder headers. - ---- a/include/drv_types.h -+++ b/include/drv_types.h -@@ -24,7 +24,7 @@ - #include - #include - #include --#include -+#include - #include - #include - #include diff --git a/package/kernel/rtl8812au-ac/patches/010-disable-default-build-x86.patch b/package/kernel/rtl8812au-ac/patches/010-disable-default-build-x86.patch deleted file mode 100644 index d2621542e..000000000 --- a/package/kernel/rtl8812au-ac/patches/010-disable-default-build-x86.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/Makefile -+++ b/Makefile -@@ -92,7 +92,7 @@ CONFIG_RTW_SDIO_PM_KEEP_POWER = y - ###################### MP HW TX MODE FOR VHT ####################### - CONFIG_MP_VHT_HW_TX_MODE = n - ###################### Platform Related ####################### --CONFIG_PLATFORM_I386_PC = y -+CONFIG_PLATFORM_I386_PC = n - CONFIG_PLATFORM_ANDROID_ARM64 = n - CONFIG_PLATFORM_ARM_RPI = n - CONFIG_PLATFORM_ARM64_RPI = n diff --git a/package/kernel/rtl8812au-ac/patches/020-change-value-of-vht-enable-and-usb-mode.patch b/package/kernel/rtl8812au-ac/patches/020-change-value-of-vht-enable-and-usb-mode.patch deleted file mode 100644 index 8a57356c1..000000000 --- a/package/kernel/rtl8812au-ac/patches/020-change-value-of-vht-enable-and-usb-mode.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/os_dep/linux/os_intfs.c -+++ b/os_dep/linux/os_intfs.c -@@ -254,7 +254,7 @@ int rtw_bfee_rf_number = 0; /*BeamformeeCapRfNum Rf path number, 0 for auto, ot - #endif /* CONFIG_80211N_HT */ - - #ifdef CONFIG_80211AC_VHT --int rtw_vht_enable = 1; /* 0:disable, 1:enable, 2:force auto enable */ -+int rtw_vht_enable = 2; /* 0:disable, 1:enable, 2:force auto enable */ - module_param(rtw_vht_enable, int, 0644); - - int rtw_ampdu_factor = 7; -@@ -324,7 +324,7 @@ int rtw_drv_ant_band_switch = 1; /* 0:OFF , 1:ON, Driver control antenna band sw - int rtw_single_ant_path; /*0:main ant , 1:aux ant , Fixed single antenna path, default main ant*/ - - /* 0: doesn't switch, 1: switch from usb2.0 to usb 3.0 2: switch from usb3.0 to usb 2.0 */ --int rtw_switch_usb_mode = 0; -+int rtw_switch_usb_mode = 1; - - #ifdef CONFIG_USB_AUTOSUSPEND - int rtw_enusbss = 1;/* 0:disable,1:enable */ diff --git a/package/kernel/rtl8812au-ac/patches/030-add-missing-code-for-concurrent-mode.patch b/package/kernel/rtl8812au-ac/patches/030-add-missing-code-for-concurrent-mode.patch deleted file mode 100644 index f6af34d3e..000000000 --- a/package/kernel/rtl8812au-ac/patches/030-add-missing-code-for-concurrent-mode.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/os_dep/linux/os_intfs.c -+++ b/os_dep/linux/os_intfs.c -@@ -2803,6 +2803,7 @@ static int netdev_vir_if_close(struct net_device *pnetdev) - { - _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; -+ struct wireless_dev *wdev = padapter->rtw_wdev; - - RTW_INFO(FUNC_NDEV_FMT" , bup=%d\n", FUNC_NDEV_ARG(pnetdev), padapter->bup); - padapter->net_closed = _TRUE; diff --git a/package/kernel/rtl8812au-ac/patches/040-wireless-5.8.patch b/package/kernel/rtl8812au-ac/patches/040-wireless-5.8.patch deleted file mode 100644 index 6fb74745d..000000000 --- a/package/kernel/rtl8812au-ac/patches/040-wireless-5.8.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/os_dep/linux/ioctl_cfg80211.c -+++ b/os_dep/linux/ioctl_cfg80211.c -@@ -7733,7 +7733,7 @@ exit: - return ret; - } - --#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,8,0)) -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,8,0)) || defined(BUILD_OPENWRT) - static void cfg80211_rtw_update_mgmt_frame_register(struct wiphy *wiphy, - struct wireless_dev *wdev, - struct mgmt_frame_regs *upd) -@@ -10185,7 +10185,7 @@ static struct cfg80211_ops rtw_cfg80211_ops = { - - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE) - .mgmt_tx = cfg80211_rtw_mgmt_tx, --#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,8,0)) -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,8,0)) || defined(BUILD_OPENWRT) - .update_mgmt_frame_registrations = cfg80211_rtw_update_mgmt_frame_register, - #else - .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register, diff --git a/package/kernel/rtl8812au-ct/Makefile b/package/kernel/rtl8812au-ct/Makefile index fa2cd295a..e987aceb8 100644 --- a/package/kernel/rtl8812au-ct/Makefile +++ b/package/kernel/rtl8812au-ct/Makefile @@ -7,10 +7,10 @@ PKG_LICENSE:=GPLv2 PKG_LICENSE_FILES:= PKG_SOURCE_URL:=https://github.com/greearb/rtl8812AU_8821AU_linux.git -PKG_MIRROR_HASH:=aee819df4ba83251b59bd1d4f412287b27105e5de9284bb09579f0e1a1538328 +PKG_MIRROR_HASH:=31e658df3e4d4c18c396259c2e0bef2bfc44a4aa870931f031a31e948be98af4 PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2020-12-07 -PKG_SOURCE_VERSION:=1e9689c89fa627d2d764ba0e8359fd444fe8458f +PKG_SOURCE_DATE:=2021-11-07 +PKG_SOURCE_VERSION:=39df55967b7de9f6c9600017b724303f95a8b9e2 PKG_MAINTAINER:=Ben Greear PKG_BUILD_PARALLEL:=1 @@ -44,8 +44,7 @@ NOSTDINC_FLAGS := \ NOSTDINC_FLAGS+=-DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT -DBUILD_OPENWRT define Build/Compile - +$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \ - $(KERNEL_MAKE_FLAGS) \ + +$(KERNEL_MAKE) $(PKG_JOBS) \ M="$(PKG_BUILD_DIR)" \ NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \ modules diff --git a/package/kernel/rtl8812au-ct/patches/004-remove-extern-inline.patch b/package/kernel/rtl8812au-ct/patches/004-remove-extern-inline.patch new file mode 100644 index 000000000..871fe1063 --- /dev/null +++ b/package/kernel/rtl8812au-ct/patches/004-remove-extern-inline.patch @@ -0,0 +1,24 @@ +--- a/include/ieee80211.h ++++ b/include/ieee80211.h +@@ -1313,18 +1313,18 @@ enum ieee80211_state { + (((Addr[2]) & 0xff) == 0xff) && (((Addr[3]) & 0xff) == 0xff) && (((Addr[4]) & 0xff) == 0xff) && \ + (((Addr[5]) & 0xff) == 0xff)) + #else +-extern __inline int is_multicast_mac_addr(const u8 *addr) ++__inline static int is_multicast_mac_addr(const u8 *addr) + { + return ((addr[0] != 0xff) && (0x01 & addr[0])); + } + +-extern __inline int is_broadcast_mac_addr(const u8 *addr) ++__inline static int is_broadcast_mac_addr(const u8 *addr) + { + return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \ + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff)); + } + +-extern __inline int is_zero_mac_addr(const u8 *addr) ++__inline static int is_zero_mac_addr(const u8 *addr) + { + return ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && \ + (addr[3] == 0x00) && (addr[4] == 0x00) && (addr[5] == 0x00)); diff --git a/package/kernel/rtw88-usb/Makefile b/package/kernel/rtw88-usb/Makefile new file mode 100644 index 000000000..10536b6b4 --- /dev/null +++ b/package/kernel/rtw88-usb/Makefile @@ -0,0 +1,132 @@ +# +# Copyright (C) 2017 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=rtw88-usb +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2021-07-06 +PKG_SOURCE_URL:=https://github.com/ulli-kroll/rtw88-usb.git +PKG_SOURCE_VERSION:=dd05eec8e5ac934b3d8e67e8008228f842b4ce1c +PKG_MIRROR_HASH:=9932f69573a3469d1eba403c7964a9472530fcfa1c29356babeecdad8d9c6991 + +PKG_BUILD_PARALLEL:=1 +PKG_LICENSE:=GPL-2.0 +PKG_LICENSE_FILES:=LICENSE + +STAMP_CONFIGURED_DEPENDS := $(STAGING_DIR)/usr/include/mac80211-backport/backport/autoconf.h + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/rtw88-default + SUBMENU:=Wireless Drivers + TITLE:=Realtek rtw88 family usb driver + DEPENDS:=+kmod-mac80211 +kmod-usb-core \ + +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +endef + +define KernelPackage/rtw88-usb + $(KernelPackage/rtw88-default) + HIDDEN:=1 + FILES:= \ + $(PKG_BUILD_DIR)/rtw88_usb.ko \ + $(PKG_BUILD_DIR)/rtw88_core.ko +endef + +define KernelPackage/rtl8723du + $(KernelPackage/rtw88-default) + TITLE:=Realtek RTL8723DU support + DEPENDS+=+kmod-rtw88-usb +rtl8723du-firmware + FILES:= \ + $(PKG_BUILD_DIR)/rtw88_8723d.ko \ + $(PKG_BUILD_DIR)/rtw88_8723du.ko + AUTOLOAD:=$(call AutoProbe,rtw88_8723du) +endef + +define KernelPackage/rtl8821cu + $(KernelPackage/rtw88-default) + TITLE:=Realtek RTL8821CU support + DEPENDS+=+kmod-rtw88-usb +rtl8821ce-firmware + FILES:= \ + $(PKG_BUILD_DIR)/rtw88_8821c.ko \ + $(PKG_BUILD_DIR)/rtw88_8821cu.ko + AUTOLOAD:=$(call AutoProbe,rtw88_8821cu) +endef + +define KernelPackage/rtl8822bu + $(KernelPackage/rtw88-default) + TITLE:=Realtek RTL8822BU support + DEPENDS+=+kmod-rtw88-usb +rtl8822be-firmware + FILES:= \ + $(PKG_BUILD_DIR)/rtw88_8822b.ko \ + $(PKG_BUILD_DIR)/rtw88_8822bu.ko + AUTOLOAD:=$(call AutoProbe,rtw88_8822bu) +endef + +define KernelPackage/rtl8822cu + $(KernelPackage/rtw88-default) + TITLE:=Realtek RTL8822CU support + DEPENDS+=+kmod-rtw88-usb +rtl8822ce-firmware + FILES:= \ + $(PKG_BUILD_DIR)/rtw88_8822c.ko \ + $(PKG_BUILD_DIR)/rtw88_8822cu.ko + AUTOLOAD:=$(call AutoProbe,rtw88_8822cu) +endef + +NOSTDINC_FLAGS := \ + $(KERNEL_NOSTDINC_FLAGS) \ + -I$(PKG_BUILD_DIR) \ + -I$(STAGING_DIR)/usr/include/mac80211-backport/uapi \ + -I$(STAGING_DIR)/usr/include/mac80211-backport \ + -I$(STAGING_DIR)/usr/include/mac80211/uapi \ + -I$(STAGING_DIR)/usr/include/mac80211 \ + -include backport/autoconf.h \ + -include backport/backport.h + +ifdef CONFIG_PACKAGE_kmod-rtw88-usb +PKG_MAKE_FLAGS += \ + CONFIG_RTW88_USB=m \ + CONFIG_RTW88_CORE=m +endif +ifdef CONFIG_PACKAGE_kmod-rtl8723du + PKG_MAKE_FLAGS += \ + CONFIG_RTW88_8723D=m \ + CONFIG_RTW88_8723DU=m +endif +ifdef CONFIG_PACKAGE_kmod-rtl8821cu + PKG_MAKE_FLAGS += \ + CONFIG_RTW88_8821C=m \ + CONFIG_RTW88_8821CU=m +endif +ifdef CONFIG_PACKAGE_kmod-rtl8822bu + PKG_MAKE_FLAGS += \ + CONFIG_RTW88_8822B=m \ + CONFIG_RTW88_8822BU=m +endif +ifdef CONFIG_PACKAGE_kmod-rtl8822cu + PKG_MAKE_FLAGS += \ + CONFIG_RTW88_8822C=m \ + CONFIG_RTW88_8822CU=m +endif + +define Build/Compile + +$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \ + $(KERNEL_MAKE_FLAGS) \ + $(PKG_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)" \ + NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \ + modules +endef + +$(eval $(call KernelPackage,rtw88-usb)) +$(eval $(call KernelPackage,rtl8723du)) +$(eval $(call KernelPackage,rtl8821cu)) +$(eval $(call KernelPackage,rtl8822bu)) +$(eval $(call KernelPackage,rtl8822cu)) diff --git a/package/kernel/rtw88-usb/patches/001-sync-upstream-regd.patch b/package/kernel/rtw88-usb/patches/001-sync-upstream-regd.patch new file mode 100644 index 000000000..8b4843088 --- /dev/null +++ b/package/kernel/rtw88-usb/patches/001-sync-upstream-regd.patch @@ -0,0 +1,391 @@ +--- a/debug.c ++++ b/debug.c +@@ -868,37 +868,6 @@ static int rtw_debugfs_get_coex_enable(struct seq_file *m, void *v) + return 0; + } + +-static ssize_t rtw_debugfs_set_edcca_enable(struct file *filp, +- const char __user *buffer, +- size_t count, loff_t *loff) +-{ +- struct seq_file *seqpriv = (struct seq_file *)filp->private_data; +- struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; +- struct rtw_dev *rtwdev = debugfs_priv->rtwdev; +- char tmp[32 + 1]; +- int err; +- +- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); +- +- err = kstrtobool(tmp, &rtw_edcca_enabled); +- if (err) +- return err; +- rtw_phy_adaptivity_set_mode(rtwdev); +- +- return count; +-} +- +-static int rtw_debugfs_get_edcca_enable(struct seq_file *m, void *v) +-{ +- struct rtw_debugfs_priv *debugfs_priv = m->private; +- struct rtw_dev *rtwdev = debugfs_priv->rtwdev; +- struct rtw_dm_info *dm_info = &rtwdev->dm_info; +- +- seq_printf(m, "EDCCA mode %d\n", dm_info->edcca_mode); +- +- return 0; +-} +- + static ssize_t rtw_debugfs_set_fw_crash(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +@@ -1118,11 +1087,6 @@ static struct rtw_debugfs_priv rtw_debug_priv_coex_info = { + .cb_read = rtw_debugfs_get_coex_info, + }; + +-static struct rtw_debugfs_priv rtw_debug_priv_edcca_enable = { +- .cb_write = rtw_debugfs_set_edcca_enable, +- .cb_read = rtw_debugfs_get_edcca_enable, +-}; +- + static struct rtw_debugfs_priv rtw_debug_priv_fw_crash = { + .cb_write = rtw_debugfs_set_fw_crash, + .cb_read = rtw_debugfs_get_fw_crash, +@@ -1209,7 +1173,6 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev) + rtw_debugfs_add_r(tx_pwr_tbl); + rtw_debugfs_add_rw(fw_crash); + rtw_debugfs_add_rw(dm_cap); +- rtw_debugfs_add_rw(edcca_enable); + } + + #endif /* CONFIG_RTW88_DEBUGFS */ +--- a/phy.c ++++ b/phy.c +@@ -9,7 +9,6 @@ + #include "fw.h" + #include "phy.h" + #include "debug.h" +-#include "regd.h" + + struct phy_cfg_pair { + u32 addr; +@@ -121,58 +120,6 @@ static void rtw_phy_cck_pd_init(struct rtw_dev *rtwdev) + dm_info->cck_fa_avg = CCK_FA_AVG_RESET; + } + +-void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l) +-{ +- struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th; +- +- rtw_write32_mask(rtwdev, +- edcca_th[EDCCA_TH_L2H_IDX].hw_reg.addr, +- edcca_th[EDCCA_TH_L2H_IDX].hw_reg.mask, +- l2h + edcca_th[EDCCA_TH_L2H_IDX].offset); +- rtw_write32_mask(rtwdev, +- edcca_th[EDCCA_TH_H2L_IDX].hw_reg.addr, +- edcca_th[EDCCA_TH_H2L_IDX].hw_reg.mask, +- h2l + edcca_th[EDCCA_TH_H2L_IDX].offset); +-} +-EXPORT_SYMBOL(rtw_phy_set_edcca_th); +- +-void rtw_phy_adaptivity_set_mode(struct rtw_dev *rtwdev) +-{ +- struct rtw_chip_info *chip = rtwdev->chip; +- struct rtw_dm_info *dm_info = &rtwdev->dm_info; +- +- /* turn off in debugfs for debug usage */ +- if (!rtw_edcca_enabled) { +- dm_info->edcca_mode = RTW_EDCCA_NORMAL; +- rtw_dbg(rtwdev, RTW_DBG_PHY, "EDCCA disabled, cannot be set\n"); +- return; +- } +- +- switch (rtwdev->regd.region) { +- case NL80211_DFS_ETSI: +- dm_info->edcca_mode = RTW_EDCCA_ADAPTIVITY; +- dm_info->l2h_th_ini = chip->l2h_th_ini_ad; +- break; +- case NL80211_DFS_JP: +- dm_info->edcca_mode = RTW_EDCCA_ADAPTIVITY; +- dm_info->l2h_th_ini = chip->l2h_th_ini_cs; +- break; +- default: +- dm_info->edcca_mode = RTW_EDCCA_NORMAL; +- break; +- } +-} +- +-static void rtw_phy_adaptivity_init(struct rtw_dev *rtwdev) +-{ +- struct rtw_chip_info *chip = rtwdev->chip; +- +- rtw_regd_init_dfs_region(rtwdev, rtwdev->regd.region); +- rtw_phy_adaptivity_set_mode(rtwdev); +- if (chip->ops->adaptivity_init) +- chip->ops->adaptivity_init(rtwdev); +-} +- + static void rtw_phy_cfo_init(struct rtw_dev *rtwdev) + { + struct rtw_chip_info *chip = rtwdev->chip; +@@ -202,8 +149,6 @@ void rtw_phy_init(struct rtw_dev *rtwdev) + rtw_phy_cck_pd_init(rtwdev); + + dm_info->iqk.done = false; +- dm_info->iqk.done = false; +- rtw_phy_adaptivity_init(rtwdev); + } + EXPORT_SYMBOL(rtw_phy_init); + +--- a/phy.h ++++ b/phy.h +@@ -61,8 +61,6 @@ void rtw_phy_config_swing_table(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table); + void rtw_phy_parsing_cfo(struct rtw_dev *rtwdev, + struct rtw_rx_pkt_stat *pkt_stat); +-void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l); +-void rtw_phy_adaptivity_set_mode(struct rtw_dev *rtwdev); + + struct rtw_txpwr_lmt_cfg_pair { + u8 regd; +--- a/regd.c ++++ b/regd.c +@@ -7,18 +7,6 @@ + #include "debug.h" + #include "phy.h" + +-static const struct ieee80211_regdomain rtw88_world_regdom = { +- .n_reg_rules = 5, +- .alpha2 = "99", +- .reg_rules = { +- REG_RULE(2412 - 10, 2462 + 10, 40, 0, 20, 0), +- REG_RULE(2467 - 10, 2484 + 10, 40, 0, 20, NL80211_RRF_NO_IR), +- REG_RULE(5180 - 10, 5240 + 10, 80, 0, 20, NL80211_RRF_NO_IR), +- REG_RULE(5260 - 10, 5700 + 10, 80, 0, 20, +- NL80211_RRF_NO_IR | NL80211_RRF_DFS), +- REG_RULE(5745 - 10, 5825 + 10, 80, 0, 20, NL80211_RRF_NO_IR), +- } +-}; + #define COUNTRY_CHPLAN_ENT(_alpha2, _chplan, _txpwr_regd) \ + {.alpha2 = (_alpha2), \ + .chplan = (_chplan), \ +@@ -351,73 +339,28 @@ static struct rtw_regulatory rtw_regd_find_reg_by_name(char *alpha2) + return rtw_defined_chplan; + } + +-static bool rtw_regd_is_ww(struct rtw_regulatory *reg) +-{ +- if (reg->txpwr_regd == RTW_REGD_WW) +- return true; +- return false; +-} +- +-void rtw_regd_init_dfs_region(struct rtw_dev *rtwdev, +- enum nl80211_dfs_regions curr_region) +-{ +- struct ieee80211_hw *hw = rtwdev->hw; +- const struct ieee80211_regdomain *wiphy_regd = NULL; +- +- if (curr_region != RTW_REGION_INVALID) +- return; +- +- rcu_read_lock(); +- wiphy_regd = rcu_dereference(hw->wiphy->regd); +- if (wiphy_regd) +- rtwdev->regd.region = wiphy_regd->dfs_region; +- rcu_read_unlock(); +-} +- + static int rtw_regd_notifier_apply(struct rtw_dev *rtwdev, + struct wiphy *wiphy, + struct regulatory_request *request) + { +- if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER) +- return -ENOTSUPP; +- if (request->initiator == NL80211_REGDOM_SET_BY_USER && +- !IS_ENABLED(CONFIG_RTW88_REGD_USER_REG_HINTS)) +- return -EPERM; +- if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && +- !rtw_regd_is_ww(&rtwdev->regd)) +- return -EINVAL; +- if (request->initiator == NL80211_REGDOM_SET_BY_CORE && +- !rtwdev->efuse.country_worldwide) { +- rtwdev->regd = +- rtw_regd_find_reg_by_name(rtwdev->efuse.country_code); +- /* return to the efuse setting */ +- rtw_regd_init_dfs_region(rtwdev, RTW_REGION_INVALID); ++ if (request->initiator == NL80211_REGDOM_SET_BY_USER) + return 0; +- } + rtwdev->regd = rtw_regd_find_reg_by_name(request->alpha2); + rtw_regd_apply_world_flags(wiphy, request->initiator); +- rtwdev->regd.region = request->dfs_region; + + return 0; + } + + static int +-rtw_regd_init_wiphy(struct rtw_dev *rtwdev, struct wiphy *wiphy, ++rtw_regd_init_wiphy(struct rtw_regulatory *reg, struct wiphy *wiphy, + void (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request)) + { +- struct rtw_regulatory *reg = &rtwdev->regd; +- + wiphy->reg_notifier = reg_notifier; + +- if (rtw_regd_is_ww(reg)) { +- rtwdev->efuse.country_worldwide = true; +- wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; +- wiphy_apply_custom_regulatory(wiphy, &rtw88_world_regdom); +- } else { +- rtwdev->efuse.country_worldwide = false; +- } +- wiphy->regulatory_flags |= REGULATORY_STRICT_REG; ++ wiphy->regulatory_flags &= ~REGULATORY_CUSTOM_REG; ++ wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG; ++ wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS; + + rtw_regd_apply_hw_cap_flags(wiphy); + +@@ -434,8 +377,7 @@ int rtw_regd_init(struct rtw_dev *rtwdev, + return -EINVAL; + + rtwdev->regd = rtw_regd_find_reg_by_name(rtwdev->efuse.country_code); +- rtw_regd_init_wiphy(rtwdev, wiphy, reg_notifier); +- rtwdev->regd.region = RTW_REGION_INVALID; ++ rtw_regd_init_wiphy(&rtwdev->regd, wiphy, reg_notifier); + + return 0; + } +@@ -445,21 +387,12 @@ void rtw_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request) + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct rtw_dev *rtwdev = hw->priv; + struct rtw_hal *hal = &rtwdev->hal; +- int ret; + +- ret = rtw_regd_notifier_apply(rtwdev, wiphy, request); +- if (ret) { +- rtw_warn(rtwdev, "failed to apply regulatory from initiator %d: %d\n", +- request->initiator, ret); +- return; +- } ++ rtw_regd_notifier_apply(rtwdev, wiphy, request); + rtw_dbg(rtwdev, RTW_DBG_REGD, + "get alpha2 %c%c from initiator %d, mapping to chplan 0x%x, txregd %d\n", +- request->alpha2[0], request->alpha2[1], +- request->initiator, rtwdev->regd.chplan, +- rtwdev->regd.txpwr_regd); +- +- rtw_phy_adaptivity_set_mode(rtwdev); ++ request->alpha2[0], request->alpha2[1], request->initiator, ++ rtwdev->regd.chplan, rtwdev->regd.txpwr_regd); + + rtw_phy_set_tx_power_level(rtwdev, hal->current_channel); + } +--- a/regd.h ++++ b/regd.h +@@ -68,6 +68,4 @@ int rtw_regd_init(struct rtw_dev *rtwdev, + void (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request)); + void rtw_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request); +-void rtw_regd_init_dfs_region(struct rtw_dev *rtwdev, +- enum nl80211_dfs_regions curr_region); + #endif +--- a/rtw8822b.c ++++ b/rtw8822b.c +@@ -1561,37 +1561,6 @@ static void rtw8822b_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif, + rtw_warn(rtwdev, "wrong bfee role\n"); + } + +-static void rtw8822b_adaptivity_init(struct rtw_dev *rtwdev) +-{ +- rtw_phy_set_edcca_th(rtwdev, 0x7f, 0x7f); +- /* mac edcca state setting */ +- rtw_write32_mask(rtwdev, REG_TX_PTCL_CTRL, BIT_DIS_EDCCA, 0); +- rtw_write32_mask(rtwdev, REG_RD_CTRL, BIT_EDCCA_MSK_CNTDOWN_EN, 1); +- +- rtw_write32_mask(rtwdev, REG_EDCCA_SOURCE, BIT_SOURCE_OPTION, 1); +- rtw_write32_mask(rtwdev, REG_EDCCA_POW_MA, BIT_MA_LEVEL, 0); +- /* edcca decistion opt */ +- rtw_write32_mask(rtwdev, REG_EDCCA_DECISION, BIT_EDCCA_OPTION, 1); +-} +- +-static void rtw8822b_adaptivity(struct rtw_dev *rtwdev) +-{ +- struct rtw_dm_info *dm_info = &rtwdev->dm_info; +- s8 l2h, h2l; +- u8 igi; +- +- igi = dm_info->igi_history[0]; +- if (dm_info->edcca_mode == RTW_EDCCA_NORMAL) { +- l2h = max_t(s8, igi + EDCCA_IGI_L2H_DIFF, EDCCA_TH_L2H_LB); +- h2l = l2h - EDCCA_L2H_H2L_DIFF_NORMAL; +- } else { +- l2h = min_t(s8, igi, dm_info->l2h_th_ini); +- h2l = l2h - EDCCA_L2H_H2L_DIFF; +- } +- +- rtw_phy_set_edcca_th(rtwdev, l2h, h2l); +-} +- + static void rtw8822b_fill_txdesc_checksum(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *txdesc) +@@ -2174,8 +2143,6 @@ static struct rtw_chip_ops rtw8822b_ops = { + .config_bfee = rtw8822b_bf_config_bfee, + .set_gid_table = rtw_bf_set_gid_table, + .cfg_csi_rate = rtw_bf_cfg_csi_rate, +- .adaptivity_init = rtw8822b_adaptivity_init, +- .adaptivity = rtw8822b_adaptivity, + .fill_txdesc_checksum = rtw8822b_fill_txdesc_checksum, + + .coex_set_init = rtw8822b_coex_cfg_init, +--- a/rtw8822c.c ++++ b/rtw8822c.c +@@ -4442,37 +4442,6 @@ static void rtw8822c_pwr_track(struct rtw_dev *rtwdev) + dm_info->pwr_trk_triggered = false; + } + +-static void rtw8822c_adaptivity_init(struct rtw_dev *rtwdev) +-{ +- rtw_phy_set_edcca_th(rtwdev, 0x7f, 0x7f); +- /* mac edcca state setting */ +- rtw_write32_mask(rtwdev, REG_TX_PTCL_CTRL, BIT_DIS_EDCCA, 0); +- rtw_write32_mask(rtwdev, REG_RD_CTRL, BIT_EDCCA_MSK_CNTDOWN_EN, 1); +- /* edcca decistion opt */ +- rtw_write32_mask(rtwdev, REG_EDCCA_DECISION, BIT_EDCCA_OPTION, 0); +-} +- +-static void rtw8822c_adaptivity(struct rtw_dev *rtwdev) +-{ +- struct rtw_dm_info *dm_info = &rtwdev->dm_info; +- s8 l2h, h2l; +- u8 igi; +- +- igi = dm_info->igi_history[0]; +- if (dm_info->edcca_mode == RTW_EDCCA_NORMAL) { +- l2h = max_t(s8, igi + EDCCA_IGI_L2H_DIFF, EDCCA_TH_L2H_LB); +- h2l = l2h - EDCCA_L2H_H2L_DIFF_NORMAL; +- } else { +- if (igi < dm_info->l2h_th_ini - EDCCA_ADC_BACKOFF) +- l2h = igi + EDCCA_ADC_BACKOFF; +- else +- l2h = dm_info->l2h_th_ini; +- h2l = l2h - EDCCA_L2H_H2L_DIFF; +- } +- +- rtw_phy_set_edcca_th(rtwdev, l2h, h2l); +-} +- + static void rtw8822c_fill_txdesc_checksum(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *txdesc) +@@ -4903,8 +4872,6 @@ static struct rtw_chip_ops rtw8822c_ops = { + .cfg_csi_rate = rtw_bf_cfg_csi_rate, + .cfo_init = rtw8822c_cfo_init, + .cfo_track = rtw8822c_cfo_track, +- .adaptivity_init = rtw8822c_adaptivity_init, +- .adaptivity = rtw8822c_adaptivity, + .fill_txdesc_checksum = rtw8822c_fill_txdesc_checksum, + + .coex_set_init = rtw8822c_coex_cfg_init, diff --git a/package/kernel/rtw88-usb/patches/002-drop-rf_lock.patch b/package/kernel/rtw88-usb/patches/002-drop-rf_lock.patch new file mode 100644 index 000000000..5255721af --- /dev/null +++ b/package/kernel/rtw88-usb/patches/002-drop-rf_lock.patch @@ -0,0 +1,124 @@ +From d57ca103e54e2b3eea7e2603548c58bcc4155541 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer +Date: Fri, 2 Dec 2022 09:12:16 +0100 +Subject: [PATCH] wifi: rtw88: Drop rf_lock + +The rtwdev->rf_lock spinlock protects the rf register accesses in +rtw_read_rf() and rtw_write_rf(). Most callers of these functions hold +rtwdev->mutex already with the exception of the callsites in the debugfs +code. The debugfs code doesn't justify an extra lock, so acquire the mutex +there as well before calling rf register accessors and drop the now +unnecessary spinlock. + +Signed-off-by: Sascha Hauer +--- + +--- a/debug.c ++++ b/debug.c +@@ -144,7 +144,9 @@ static int rtw_debugfs_get_rf_read(struct seq_file *m, void *v) + addr = debugfs_priv->rf_addr; + mask = debugfs_priv->rf_mask; + ++ mutex_lock(&rtwdev->mutex); + val = rtw_read_rf(rtwdev, path, addr, mask); ++ mutex_unlock(&rtwdev->mutex); + + seq_printf(m, "rf_read path:%d addr:0x%08x mask:0x%08x val=0x%08x\n", + path, addr, mask, val); +@@ -418,7 +420,9 @@ static ssize_t rtw_debugfs_set_rf_write(struct file *filp, + return count; + } + ++ mutex_lock(&rtwdev->mutex); + rtw_write_rf(rtwdev, path, addr, mask, val); ++ mutex_unlock(&rtwdev->mutex); + rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, + "write_rf path:%d addr:0x%08x mask:0x%08x, val:0x%08x\n", + path, addr, mask, val); +@@ -523,6 +527,8 @@ static int rtw_debug_get_rf_dump(struct seq_file *m, void *v) + u32 addr, offset, data; + u8 path; + ++ mutex_lock(&rtwdev->mutex); ++ + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + seq_printf(m, "RF path:%d\n", path); + for (addr = 0; addr < 0x100; addr += 4) { +@@ -537,6 +543,8 @@ static int rtw_debug_get_rf_dump(struct seq_file *m, void *v) + seq_puts(m, "\n"); + } + ++ mutex_unlock(&rtwdev->mutex); ++ + return 0; + } + +@@ -1027,6 +1035,8 @@ static void dump_gapk_status(struct rtw_dev *rtwdev, struct seq_file *m) + dm_info->dm_flags & BIT(RTW_DM_CAP_TXGAPK) ? '-' : '+', + rtw_dm_cap_strs[RTW_DM_CAP_TXGAPK]); + ++ mutex_lock(&rtwdev->mutex); ++ + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + val = rtw_read_rf(rtwdev, path, RF_GAINTX, RFREG_MASK); + seq_printf(m, "path %d:\n0x%x = 0x%x\n", path, RF_GAINTX, val); +@@ -1036,6 +1046,7 @@ static void dump_gapk_status(struct rtw_dev *rtwdev, struct seq_file *m) + txgapk->rf3f_fs[path][i], i); + seq_puts(m, "\n"); + } ++ mutex_unlock(&rtwdev->mutex); + } + + static int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v) +--- a/hci.h ++++ b/hci.h +@@ -166,12 +166,11 @@ static inline u32 + rtw_read_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask) + { +- unsigned long flags; + u32 val; + +- spin_lock_irqsave(&rtwdev->rf_lock, flags); ++ lockdep_assert_held(&rtwdev->mutex); ++ + val = rtwdev->chip->ops->read_rf(rtwdev, rf_path, addr, mask); +- spin_unlock_irqrestore(&rtwdev->rf_lock, flags); + + return val; + } +@@ -180,11 +179,9 @@ static inline void + rtw_write_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask, u32 data) + { +- unsigned long flags; ++ lockdep_assert_held(&rtwdev->mutex); + +- spin_lock_irqsave(&rtwdev->rf_lock, flags); + rtwdev->chip->ops->write_rf(rtwdev, rf_path, addr, mask, data); +- spin_unlock_irqrestore(&rtwdev->rf_lock, flags); + } + + static inline u32 +--- a/main.c ++++ b/main.c +@@ -1994,7 +1994,6 @@ int rtw_core_init(struct rtw_dev *rtwdev) + skb_queue_head_init(&rtwdev->coex.queue); + skb_queue_head_init(&rtwdev->tx_report.queue); + +- spin_lock_init(&rtwdev->rf_lock); + spin_lock_init(&rtwdev->h2c.lock); + spin_lock_init(&rtwdev->txq_lock); + spin_lock_init(&rtwdev->tx_report.q_lock); +--- a/main.h ++++ b/main.h +@@ -1994,9 +1994,6 @@ struct rtw_dev { + /* ensures exclusive access from mac80211 callbacks */ + struct mutex mutex; + +- /* read/write rf register */ +- spinlock_t rf_lock; +- + /* watch dog every 2 sec */ + struct delayed_work watch_dog_work; + u32 watch_dog_cnt; diff --git a/package/kernel/rtw88-usb/patches/003-drop-h2c-lock.patch b/package/kernel/rtw88-usb/patches/003-drop-h2c-lock.patch new file mode 100644 index 000000000..d28cbfd8f --- /dev/null +++ b/package/kernel/rtw88-usb/patches/003-drop-h2c-lock.patch @@ -0,0 +1,103 @@ +From 1e2701f4079a7906ff3fb43a315925d303e289d8 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer +Date: Fri, 2 Dec 2022 09:12:17 +0100 +Subject: [PATCH] wifi: rtw88: Drop h2c.lock + +The h2c.lock spinlock is used in rtw_fw_send_h2c_command() and +rtw_fw_send_h2c_packet(). Most callers call this with rtwdev->mutex +held, except from one callsite in the debugfs code. The debugfs code +alone doesn't justify the extra lock, so acquire rtwdev->mutex in +debugfs and drop the now unnecessary spinlock. + +Signed-off-by: Sascha Hauer +--- + +--- a/debug.c ++++ b/debug.c +@@ -396,7 +396,9 @@ static ssize_t rtw_debugfs_set_h2c(struct file *filp, + return -EINVAL; + } + ++ mutex_lock(&rtwdev->mutex); + rtw_fw_h2c_cmd_dbg(rtwdev, param); ++ mutex_unlock(&rtwdev->mutex); + + return count; + } +--- a/fw.c ++++ b/fw.c +@@ -320,7 +320,7 @@ static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev, + h2c[3], h2c[2], h2c[1], h2c[0], + h2c[7], h2c[6], h2c[5], h2c[4]); + +- spin_lock(&rtwdev->h2c.lock); ++ lockdep_assert_held(&rtwdev->mutex); + + box = rtwdev->h2c.last_box_num; + switch (box) { +@@ -342,7 +342,7 @@ static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev, + break; + default: + WARN(1, "invalid h2c mail box number\n"); +- goto out; ++ return; + } + + ret = read_poll_timeout_atomic(rtw_read8, box_state, +@@ -351,7 +351,7 @@ static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev, + + if (ret) { + rtw_err(rtwdev, "failed to send h2c command\n"); +- goto out; ++ return; + } + + for (idx = 0; idx < 4; idx++) +@@ -361,9 +361,6 @@ static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev, + + if (++rtwdev->h2c.last_box_num >= 4) + rtwdev->h2c.last_box_num = 0; +- +-out: +- spin_unlock(&rtwdev->h2c.lock); + } + + void rtw_fw_h2c_cmd_dbg(struct rtw_dev *rtwdev, u8 *h2c) +@@ -375,15 +372,13 @@ static void rtw_fw_send_h2c_packet(struct rtw_dev *rtwdev, u8 *h2c_pkt) + { + int ret; + +- spin_lock(&rtwdev->h2c.lock); ++ lockdep_assert_held(&rtwdev->mutex); + + FW_OFFLOAD_H2C_SET_SEQ_NUM(h2c_pkt, rtwdev->h2c.seq); + ret = rtw_hci_write_data_h2c(rtwdev, h2c_pkt, H2C_PKT_SIZE); + if (ret) + rtw_err(rtwdev, "failed to send h2c packet\n"); + rtwdev->h2c.seq++; +- +- spin_unlock(&rtwdev->h2c.lock); + } + + void +--- a/main.c ++++ b/main.c +@@ -1994,7 +1994,6 @@ int rtw_core_init(struct rtw_dev *rtwdev) + skb_queue_head_init(&rtwdev->coex.queue); + skb_queue_head_init(&rtwdev->tx_report.queue); + +- spin_lock_init(&rtwdev->h2c.lock); + spin_lock_init(&rtwdev->txq_lock); + spin_lock_init(&rtwdev->tx_report.q_lock); + +--- a/main.h ++++ b/main.h +@@ -2018,8 +2018,6 @@ struct rtw_dev { + struct { + /* incicate the mail box to use with fw */ + u8 last_box_num; +- /* protect to send h2c to fw */ +- spinlock_t lock; + u32 seq; + } h2c; + diff --git a/package/kernel/rtw88-usb/patches/004-drop-coex-mutex.patch b/package/kernel/rtw88-usb/patches/004-drop-coex-mutex.patch new file mode 100644 index 000000000..cd3af524a --- /dev/null +++ b/package/kernel/rtw88-usb/patches/004-drop-coex-mutex.patch @@ -0,0 +1,74 @@ +From 8647f7f0b9080bc2d2f6e02524782f2f02f159bc Mon Sep 17 00:00:00 2001 +From: Sascha Hauer +Date: Fri, 2 Dec 2022 09:12:18 +0100 +Subject: [PATCH] wifi: rtw88: Drop coex mutex + +coex->mutex is used in rtw_coex_info_request() only. Most callers of this +function hold rtwdev->mutex already, except for one callsite in the +debugfs code. The debugfs code alone doesn't justify the extra lock, so +acquire rtwdev->mutex there as well and drop the now unnecessary +spinlock. + +Signed-off-by: Sascha Hauer +--- + +--- a/coex.c ++++ b/coex.c +@@ -633,7 +633,7 @@ static struct sk_buff *rtw_coex_info_request(struct rtw_dev *rtwdev, + struct rtw_coex *coex = &rtwdev->coex; + struct sk_buff *skb_resp = NULL; + +- mutex_lock(&coex->mutex); ++ lockdep_assert_held(&rtwdev->mutex); + + rtw_fw_query_bt_mp_info(rtwdev, req); + +@@ -650,7 +650,6 @@ static struct sk_buff *rtw_coex_info_request(struct rtw_dev *rtwdev, + } + + out: +- mutex_unlock(&coex->mutex); + return skb_resp; + } + +--- a/debug.c ++++ b/debug.c +@@ -842,7 +842,9 @@ static int rtw_debugfs_get_coex_info(struct seq_file *m, void *v) + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + ++ mutex_lock(&rtwdev->mutex); + rtw_coex_display_coex_info(rtwdev, m); ++ mutex_unlock(&rtwdev->mutex); + + return 0; + } +--- a/main.c ++++ b/main.c +@@ -1998,7 +1998,6 @@ int rtw_core_init(struct rtw_dev *rtwdev) + spin_lock_init(&rtwdev->tx_report.q_lock); + + mutex_init(&rtwdev->mutex); +- mutex_init(&rtwdev->coex.mutex); + mutex_init(&rtwdev->hal.tx_power_mutex); + + init_waitqueue_head(&rtwdev->coex.wait); +@@ -2066,7 +2065,6 @@ void rtw_core_deinit(struct rtw_dev *rtwdev) + } + + mutex_destroy(&rtwdev->mutex); +- mutex_destroy(&rtwdev->coex.mutex); + mutex_destroy(&rtwdev->hal.tx_power_mutex); + } + EXPORT_SYMBOL(rtw_core_deinit); +--- a/main.h ++++ b/main.h +@@ -1507,8 +1507,6 @@ struct rtw_coex_stat { + }; + + struct rtw_coex { +- /* protects coex info request section */ +- struct mutex mutex; + struct sk_buff_head queue; + wait_queue_head_t wait; + diff --git a/package/kernel/rtw88-usb/patches/005-iterate-over-vif-sta-list-non-atomically.patch b/package/kernel/rtw88-usb/patches/005-iterate-over-vif-sta-list-non-atomically.patch new file mode 100644 index 000000000..87369f827 --- /dev/null +++ b/package/kernel/rtw88-usb/patches/005-iterate-over-vif-sta-list-non-atomically.patch @@ -0,0 +1,196 @@ +From 78d5bf925f30bf9f79a69ce77386902672defe68 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer +Date: Fri, 2 Dec 2022 09:12:19 +0100 +Subject: [PATCH] wifi: rtw88: iterate over vif/sta list non-atomically + +The driver uses ieee80211_iterate_active_interfaces_atomic() +and ieee80211_iterate_stations_atomic() in several places and does +register accesses in the iterators. This doesn't cope with upcoming +USB support as registers can only be accessed non-atomically. + +Split these into a two stage process: First use the atomic iterator +functions to collect all active interfaces or stations on a list, then +iterate over the list non-atomically and call the iterator on each +entry. + +Signed-off-by: Sascha Hauer +Suggested-by: Ping-Ke shih +--- + +--- a/phy.c ++++ b/phy.c +@@ -300,7 +300,7 @@ static void rtw_phy_stat_rssi(struct rtw_dev *rtwdev) + + data.rtwdev = rtwdev; + data.min_rssi = U8_MAX; +- rtw_iterate_stas_atomic(rtwdev, rtw_phy_stat_rssi_iter, &data); ++ rtw_iterate_stas(rtwdev, rtw_phy_stat_rssi_iter, &data); + + dm_info->pre_min_rssi = dm_info->min_rssi; + dm_info->min_rssi = data.min_rssi; +@@ -544,7 +544,7 @@ static void rtw_phy_ra_info_update(struct rtw_dev *rtwdev) + if (rtwdev->watch_dog_cnt & 0x3) + return; + +- rtw_iterate_stas_atomic(rtwdev, rtw_phy_ra_info_update_iter, rtwdev); ++ rtw_iterate_stas(rtwdev, rtw_phy_ra_info_update_iter, rtwdev); + } + + static u32 rtw_phy_get_rrsr_mask(struct rtw_dev *rtwdev, u8 rate_idx) +@@ -597,7 +597,7 @@ static void rtw_phy_rrsr_update(struct rtw_dev *rtwdev) + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + dm_info->rrsr_mask_min = RRSR_RATE_ORDER_MAX; +- rtw_iterate_stas_atomic(rtwdev, rtw_phy_rrsr_mask_min_iter, rtwdev); ++ rtw_iterate_stas(rtwdev, rtw_phy_rrsr_mask_min_iter, rtwdev); + rtw_write32(rtwdev, REG_RRSR, dm_info->rrsr_val_init & dm_info->rrsr_mask_min); + } + +--- a/ps.c ++++ b/ps.c +@@ -58,7 +58,7 @@ int rtw_leave_ips(struct rtw_dev *rtwdev) + return ret; + } + +- rtw_iterate_vifs_atomic(rtwdev, rtw_restore_port_cfg_iter, rtwdev); ++ rtw_iterate_vifs(rtwdev, rtw_restore_port_cfg_iter, rtwdev); + + rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); + +--- a/util.c ++++ b/util.c +@@ -105,3 +105,106 @@ void rtw_desc_to_mcsrate(u16 rate, u8 *mcs, u8 *nss) + *mcs = rate - DESC_RATEMCS0; + } + } ++ ++struct rtw_stas_entry { ++ struct list_head list; ++ struct ieee80211_sta *sta; ++}; ++ ++struct rtw_iter_stas_data { ++ struct rtw_dev *rtwdev; ++ struct list_head list; ++}; ++ ++static void rtw_collect_sta_iter(void *data, struct ieee80211_sta *sta) ++{ ++ struct rtw_iter_stas_data *iter_stas = data; ++ struct rtw_stas_entry *stas_entry; ++ ++ stas_entry = kmalloc(sizeof(*stas_entry), GFP_ATOMIC); ++ if (!stas_entry) ++ return; ++ ++ stas_entry->sta = sta; ++ list_add_tail(&stas_entry->list, &iter_stas->list); ++} ++ ++void rtw_iterate_stas(struct rtw_dev *rtwdev, ++ void (*iterator)(void *data, ++ struct ieee80211_sta *sta), ++ void *data) ++{ ++ struct rtw_iter_stas_data iter_data; ++ struct rtw_stas_entry *sta_entry, *tmp; ++ ++ /* &rtwdev->mutex makes sure no stations can be removed between ++ * collecting the stations and iterating over them. ++ */ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ iter_data.rtwdev = rtwdev; ++ INIT_LIST_HEAD(&iter_data.list); ++ ++ ieee80211_iterate_stations_atomic(rtwdev->hw, rtw_collect_sta_iter, ++ &iter_data); ++ ++ list_for_each_entry_safe(sta_entry, tmp, &iter_data.list, ++ list) { ++ list_del_init(&sta_entry->list); ++ iterator(data, sta_entry->sta); ++ kfree(sta_entry); ++ } ++} ++ ++struct rtw_vifs_entry { ++ struct list_head list; ++ struct ieee80211_vif *vif; ++ u8 mac[ETH_ALEN]; ++}; ++ ++struct rtw_iter_vifs_data { ++ struct rtw_dev *rtwdev; ++ struct list_head list; ++}; ++ ++void rtw_collect_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) ++{ ++ struct rtw_iter_vifs_data *iter_stas = data; ++ struct rtw_vifs_entry *vifs_entry; ++ ++ vifs_entry = kmalloc(sizeof(*vifs_entry), GFP_ATOMIC); ++ if (!vifs_entry) ++ return; ++ ++ vifs_entry->vif = vif; ++ ether_addr_copy(vifs_entry->mac, mac); ++ list_add_tail(&vifs_entry->list, &iter_stas->list); ++} ++ ++void rtw_iterate_vifs(struct rtw_dev *rtwdev, ++ void (*iterator)(void *data, u8 *mac, ++ struct ieee80211_vif *vif), ++ void *data) ++{ ++ struct rtw_iter_vifs_data iter_data; ++ struct rtw_vifs_entry *vif_entry, *tmp; ++ ++ /* &rtwdev->mutex makes sure no interfaces can be removed between ++ * collecting the interfaces and iterating over them. ++ */ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ iter_data.rtwdev = rtwdev; ++ INIT_LIST_HEAD(&iter_data.list); ++ ++ ieee80211_iterate_active_interfaces_atomic(rtwdev->hw, ++ IEEE80211_IFACE_ITER_NORMAL, ++ rtw_collect_vif_iter, &iter_data); ++ ++ list_for_each_entry_safe(vif_entry, tmp, &iter_data.list, ++ list) { ++ list_del_init(&vif_entry->list); ++ iterator(data, vif_entry->mac, vif_entry->vif); ++ kfree(vif_entry); ++ } ++} +--- a/util.h ++++ b/util.h +@@ -7,9 +7,6 @@ + + struct rtw_dev; + +-#define rtw_iterate_vifs(rtwdev, iterator, data) \ +- ieee80211_iterate_active_interfaces(rtwdev->hw, \ +- IEEE80211_IFACE_ITER_NORMAL, iterator, data) + #define rtw_iterate_vifs_atomic(rtwdev, iterator, data) \ + ieee80211_iterate_active_interfaces_atomic(rtwdev->hw, \ + IEEE80211_IFACE_ITER_NORMAL, iterator, data) +@@ -20,6 +17,15 @@ struct rtw_dev; + #define rtw_iterate_keys_rcu(rtwdev, vif, iterator, data) \ + ieee80211_iter_keys_rcu((rtwdev)->hw, vif, iterator, data) + ++void rtw_iterate_vifs(struct rtw_dev *rtwdev, ++ void (*iterator)(void *data, u8 *mac, ++ struct ieee80211_vif *vif), ++ void *data); ++void rtw_iterate_stas(struct rtw_dev *rtwdev, ++ void (*iterator)(void *data, ++ struct ieee80211_sta *sta), ++ void *data); ++ + static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr) + { + __le16 fc = hdr->frame_control; diff --git a/package/kernel/rtw88-usb/patches/100-update-makefile.patch b/package/kernel/rtw88-usb/patches/100-update-makefile.patch new file mode 100644 index 000000000..170a6bc11 --- /dev/null +++ b/package/kernel/rtw88-usb/patches/100-update-makefile.patch @@ -0,0 +1,25 @@ +--- a/Makefile ++++ b/Makefile +@@ -2,22 +2,6 @@ + KERNELDIR ?= /lib/modules/$(shell uname -r)/build + PWD := $(shell pwd) + +-CONFIG_RTW88_CORE=m +-CONFIG_RTW88_PCI=m +-CONFIG_RTW88_USB=m +-CONFIG_RTW88_8822BE=m +-CONFIG_RTW88_8822BU=m +-CONFIG_RTW88_8822B=m +-CONFIG_RTW88_8821CE=m +-CONFIG_RTW88_8821CU=m +-CONFIG_RTW88_8821C=m +-CONFIG_RTW88_8822CE=m +-CONFIG_RTW88_8822CU=m +-CONFIG_RTW88_8822C=m +-CONFIG_RTW88_8723DE=m +-CONFIG_RTW88_8723DU=m +-CONFIG_RTW88_8723D=m +- + ifneq ($(CONFIG_RTW88_8822BE),m) + ccflags-y += -DCONFIG_RTW88_8822BE=y + endif diff --git a/package/kernel/rtw88-usb/patches/101-wireless-5.14.patch b/package/kernel/rtw88-usb/patches/101-wireless-5.14.patch new file mode 100644 index 000000000..ba8ebfcda --- /dev/null +++ b/package/kernel/rtw88-usb/patches/101-wireless-5.14.patch @@ -0,0 +1,14 @@ +--- a/mac80211.c ++++ b/mac80211.c +@@ -614,7 +614,11 @@ static void rtw_ops_sw_scan_complete(struct ieee80211_hw *hw, + + static void rtw_ops_mgd_prepare_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0)) ++ struct ieee80211_prep_tx_info *info) ++#else + u16 duration) ++#endif + { + struct rtw_dev *rtwdev = hw->priv; + diff --git a/package/kernel/ubnt-ledbar/Makefile b/package/kernel/ubnt-ledbar/Makefile new file mode 100644 index 000000000..90eccf1c2 --- /dev/null +++ b/package/kernel/ubnt-ledbar/Makefile @@ -0,0 +1,34 @@ +# +# Copyright (C) 2008-2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=ubnt-ledbar +PKG_RELEASE:=1 +PKG_LICENSE:=GPL-2.0 + +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/leds-ubnt-ledbar + SUBMENU:=LED modules + TITLE:=Ubiquiti UniFi 6 LR LED support + FILES:= \ + $(PKG_BUILD_DIR)/leds-ubnt-ledbar.ko + AUTOLOAD:=$(call AutoProbe,leds-ubnt-ledbar,1) + DEPENDS:=+kmod-i2c-core +endef + +define KernelPackage/leds-ubnt-ledbar/description + LED support for some Ubiquiti UniFi access points. +endef + +define Build/Compile + $(KERNEL_MAKE) M="$(PKG_BUILD_DIR)" modules +endef + +$(eval $(call KernelPackage,leds-ubnt-ledbar)) diff --git a/package/kernel/ubnt-ledbar/src/Makefile b/package/kernel/ubnt-ledbar/src/Makefile new file mode 100644 index 000000000..a81d9377c --- /dev/null +++ b/package/kernel/ubnt-ledbar/src/Makefile @@ -0,0 +1 @@ +obj-m := leds-ubnt-ledbar.o diff --git a/package/kernel/ubnt-ledbar/src/leds-ubnt-ledbar.c b/package/kernel/ubnt-ledbar/src/leds-ubnt-ledbar.c new file mode 100644 index 000000000..555340c5e --- /dev/null +++ b/package/kernel/ubnt-ledbar/src/leds-ubnt-ledbar.c @@ -0,0 +1,255 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * Driver for the Ubiquiti RGB LED controller (LEDBAR). + * This Controller is based on a Holtek HT32F52241 and connected + * via I2C. + * + * - The Controller needs an enable signal set to high when + * performing a transaction. On the U6-LR, this is located + * at Pin 18 (R6902) + * + * - The Pin is also printed when calling the "usetled" function + * contained in the ubntapp bootloader application. + */ + +#define UBNT_LEDBAR_MAX_BRIGHTNESS 0xff + +#define UBNT_LEDBAR_TRANSACTION_LENGTH 8 +#define UBNT_LEDBAR_TRANSACTION_SUCCESS (char) 0xaa + +#define UBNT_LEDBAR_TRANSACTION_BLUE_IDX 2 +#define UBNT_LEDBAR_TRANSACTION_GREEN_IDX 3 +#define UBNT_LEDBAR_TRANSACTION_RED_IDX 4 +#define UBNT_LEDBAR_TRANSACTION_LED_COUNT_IDX 6 + +struct ubnt_ledbar { + struct mutex lock; + u32 led_count; + struct i2c_client *client; + struct led_classdev led_red; + struct led_classdev led_green; + struct led_classdev led_blue; + struct gpio_desc *enable_gpio; + struct gpio_desc *reset_gpio; +}; + +static void ubnt_ledbar_perform_transaction(struct ubnt_ledbar *ledbar, + const char *transaction, int len, + char *result, int result_len) +{ + int i; + + for (i = 0; i < len; i++) + i2c_smbus_write_byte(ledbar->client, transaction[i]); + + for (i = 0; i < result_len; i++) + result[i] = i2c_smbus_read_byte(ledbar->client); +} + +static int ubnt_ledbar_apply_state(struct ubnt_ledbar *ledbar) +{ + char setup_msg[UBNT_LEDBAR_TRANSACTION_LENGTH] = {0x40, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11}; + char led_msg[UBNT_LEDBAR_TRANSACTION_LENGTH] = {0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; + char i2c_response; + int ret = 0; + + mutex_lock(&ledbar->lock); + + led_msg[UBNT_LEDBAR_TRANSACTION_BLUE_IDX] = ledbar->led_blue.brightness; + led_msg[UBNT_LEDBAR_TRANSACTION_GREEN_IDX] = ledbar->led_green.brightness; + led_msg[UBNT_LEDBAR_TRANSACTION_RED_IDX] = ledbar->led_red.brightness; + led_msg[UBNT_LEDBAR_TRANSACTION_LED_COUNT_IDX] = ledbar->led_count; + + gpiod_set_value(ledbar->enable_gpio, 1); + + msleep(10); + + ubnt_ledbar_perform_transaction(ledbar, setup_msg, sizeof(setup_msg), &i2c_response, sizeof(i2c_response)); + if (i2c_response != UBNT_LEDBAR_TRANSACTION_SUCCESS) { + dev_err(&ledbar->client->dev, "Error initializing LED transaction: %02hhx\n", i2c_response); + ret = -EINVAL; + goto out_gpio; + } + + ubnt_ledbar_perform_transaction(ledbar, led_msg, sizeof(led_msg), &i2c_response, sizeof(i2c_response)); + if (i2c_response != UBNT_LEDBAR_TRANSACTION_SUCCESS) { + dev_err(&ledbar->client->dev, "Failed LED transaction: %02hhx\n", i2c_response); + ret = -EINVAL; + goto out_gpio; + } + + msleep(10); +out_gpio: + gpiod_set_value(ledbar->enable_gpio, 0); + + mutex_unlock(&ledbar->lock); + + return ret; +} + +static void ubnt_ledbar_reset(struct ubnt_ledbar *ledbar) +{ + static const char init_msg[16] = {0x02, 0x81, 0xfd, 0x7e, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; + char init_response[4]; + + if (!ledbar->reset_gpio) + return; + + mutex_lock(&ledbar->lock); + + gpiod_set_value(ledbar->reset_gpio, 1); + msleep(10); + gpiod_set_value(ledbar->reset_gpio, 0); + + msleep(10); + + gpiod_set_value(ledbar->enable_gpio, 1); + msleep(10); + ubnt_ledbar_perform_transaction(ledbar, init_msg, sizeof(init_msg), init_response, sizeof(init_response)); + msleep(10); + gpiod_set_value(ledbar->enable_gpio, 0); + + mutex_unlock(&ledbar->lock); +} + +#define UBNT_LEDBAR_CONTROL_RGBS(name) \ +static int ubnt_ledbar_set_##name##_brightness(struct led_classdev *led_cdev,\ + enum led_brightness value) \ +{ \ + struct ubnt_ledbar *ledbar = \ + container_of(led_cdev, struct ubnt_ledbar, led_##name); \ + int ret; \ + led_cdev->brightness = value; \ + ret = ubnt_ledbar_apply_state(ledbar); \ + return ret; \ +} + +UBNT_LEDBAR_CONTROL_RGBS(red); +UBNT_LEDBAR_CONTROL_RGBS(green); +UBNT_LEDBAR_CONTROL_RGBS(blue); + + +static int ubnt_ledbar_init_led(struct device_node *np, struct ubnt_ledbar *ledbar, + struct led_classdev *led_cdev) +{ + struct led_init_data init_data = {}; + int ret; + + if (!np) + return 0; + + init_data.fwnode = of_fwnode_handle(np); + + led_cdev->max_brightness = UBNT_LEDBAR_MAX_BRIGHTNESS; + + ret = devm_led_classdev_register_ext(&ledbar->client->dev, led_cdev, + &init_data); + if (ret) + dev_err(&ledbar->client->dev, "led register err: %d\n", ret); + + return ret; +} + + +static int ubnt_ledbar_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device_node *np = client->dev.of_node; + struct ubnt_ledbar *ledbar; + int ret; + + ledbar = devm_kzalloc(&client->dev, sizeof(*ledbar), GFP_KERNEL); + if (!ledbar) + return -ENOMEM; + + ledbar->enable_gpio = devm_gpiod_get(&client->dev, "enable", GPIOD_OUT_LOW); + + if (IS_ERR(ledbar->enable_gpio)) { + ret = PTR_ERR(ledbar->enable_gpio); + dev_err(&client->dev, "Failed to get enable gpio: %d\n", ret); + return ret; + } + + ledbar->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_LOW); + + if (IS_ERR(ledbar->reset_gpio)) { + ret = PTR_ERR(ledbar->reset_gpio); + dev_err(&client->dev, "Failed to get reset gpio: %d\n", ret); + return ret; + } + + ledbar->led_count = 1; + of_property_read_u32(np, "led-count", &ledbar->led_count); + + ledbar->client = client; + + mutex_init(&ledbar->lock); + + i2c_set_clientdata(client, ledbar); + + // Reset and initialize the MCU + ubnt_ledbar_reset(ledbar); + + ledbar->led_red.brightness_set_blocking = ubnt_ledbar_set_red_brightness; + ubnt_ledbar_init_led(of_get_child_by_name(np, "red"), ledbar, &ledbar->led_red); + + ledbar->led_green.brightness_set_blocking = ubnt_ledbar_set_green_brightness; + ubnt_ledbar_init_led(of_get_child_by_name(np, "green"), ledbar, &ledbar->led_green); + + ledbar->led_blue.brightness_set_blocking = ubnt_ledbar_set_blue_brightness; + ubnt_ledbar_init_led(of_get_child_by_name(np, "blue"), ledbar, &ledbar->led_blue); + + return ubnt_ledbar_apply_state(ledbar); +} + +static int ubnt_ledbar_remove(struct i2c_client *client) +{ + struct ubnt_ledbar *ledbar = i2c_get_clientdata(client); + + mutex_destroy(&ledbar->lock); + + return 0; +} + +static const struct i2c_device_id ubnt_ledbar_id[] = { + { "ubnt-ledbar", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ubnt_ledbar_id); + +static const struct of_device_id of_ubnt_ledbar_match[] = { + { .compatible = "ubnt,ledbar", }, + {}, +}; +MODULE_DEVICE_TABLE(of, of_ubnt_ledbar_match); + +static struct i2c_driver ubnt_ledbar_driver = { + .driver = { + .name = "ubnt-ledbar", + .of_match_table = of_ubnt_ledbar_match, + }, + .probe = ubnt_ledbar_probe, + .remove = ubnt_ledbar_remove, + .id_table = ubnt_ledbar_id, +}; +module_i2c_driver(ubnt_ledbar_driver); + +MODULE_DESCRIPTION("Ubiquiti LEDBAR driver"); +MODULE_AUTHOR("David Bauer "); +MODULE_LICENSE("GPL v2"); diff --git a/package/kernel/xr-usb-serial/Makefile b/package/kernel/xr-usb-serial/Makefile new file mode 100644 index 000000000..963bb926c --- /dev/null +++ b/package/kernel/xr-usb-serial/Makefile @@ -0,0 +1,32 @@ +# +# Copyright (C) Chen Yijun +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=xr-usb-serial +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/$(PKG_NAME) + SUBMENU:=USB Support + DEPENDS:=@GPIO_SUPPORT +kmod-usb-serial +kmod-usb2 + TITLE:=Driver for XR21V141x (used in HUAWEI UPS) + AUTOLOAD:=$(call AutoLoad,30,xr_usb_serial_common,1) + FILES:=$(PKG_BUILD_DIR)/xr_usb_serial_common.ko +endef + +define Build/Compile + $(MAKE) -C "$(LINUX_DIR)" \ + $(KERNEL_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(BUILDFLAGS)" \ + modules +endef + +$(eval $(call KernelPackage,$(PKG_NAME))) diff --git a/package/kernel/xr-usb-serial/src/Makefile b/package/kernel/xr-usb-serial/src/Makefile new file mode 100644 index 000000000..4d836ddf8 --- /dev/null +++ b/package/kernel/xr-usb-serial/src/Makefile @@ -0,0 +1,10 @@ +# +# Copyright (C) Chen Yijun +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +obj-m := xr_usb_serial_common.o + +EXTRA_CFLAGS := -DDEBUG=0 diff --git a/package/kernel/xr-usb-serial/src/xr_usb_serial_common.c b/package/kernel/xr-usb-serial/src/xr_usb_serial_common.c new file mode 100644 index 000000000..61469db4f --- /dev/null +++ b/package/kernel/xr-usb-serial/src/xr_usb_serial_common.c @@ -0,0 +1,2086 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* + * + * This driver will work with any USB UART function in these Exar devices: + * XR21V1410/1412/1414 + * XR21B1411 + * XR21B1420/1422/1424 + * XR22801/802/804 + * + * The driver has been tested on various kernel versions from 3.6.x to 5.11.x. + * This driver may work on newer versions as well. There is a different driver available + * from www.exar.com that will work with kernel versions 2.6.18 to 3.4.x. + * + * ChangeLog: + * Version 1B - Initial released version. + * Version 1C - Add 9-bit mode support + * Version 1D - GPIO support & Fixes. Check Readme for details. + */ + +//#undef DEBUG +#undef VERBOSE_DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "linux/version.h" +#include +#include +#include +#include + +#ifdef CONFIG_COMPAT +#include +#endif + +#include "xr_usb_serial_common.h" +#include "xr_usb_serial_ioctl.h" + +#define DRIVER_AUTHOR "" +#define DRIVER_DESC "Exar/MxL USB UART (serial port) driver version 1D" + +static struct usb_driver xr_usb_serial_driver; +static struct tty_driver *xr_usb_serial_tty_driver; +static struct xr_usb_serial *xr_usb_serial_table[XR_USB_SERIAL_TTY_MINORS]; + +static DEFINE_MUTEX(xr_usb_serial_table_lock); + +/* + * xr_usb_serial_table accessors + */ + +/* + * Look up an XR_USB_SERIAL structure by index. If found and not disconnected, increment + * its refcount and return it with its mutex held. + */ +static struct xr_usb_serial *xr_usb_serial_get_by_index(unsigned index) +{ + struct xr_usb_serial *xr_usb_serial; + + mutex_lock(&xr_usb_serial_table_lock); + xr_usb_serial = xr_usb_serial_table[index]; + if (xr_usb_serial) { + mutex_lock(&xr_usb_serial->mutex); + if (xr_usb_serial->disconnected) { + mutex_unlock(&xr_usb_serial->mutex); + xr_usb_serial = NULL; + } else { + tty_port_get(&xr_usb_serial->port); + mutex_unlock(&xr_usb_serial->mutex); + } + } + mutex_unlock(&xr_usb_serial_table_lock); + return xr_usb_serial; +} + +/* + * Try to find an available minor number and if found, associate it with 'xr_usb_serial'. + */ +static int xr_usb_serial_alloc_minor(struct xr_usb_serial *xr_usb_serial) +{ + int minor; + + mutex_lock(&xr_usb_serial_table_lock); + for (minor = 0; minor < XR_USB_SERIAL_TTY_MINORS; minor++) { + if (!xr_usb_serial_table[minor]) { + xr_usb_serial_table[minor] = xr_usb_serial; + break; + } + } + mutex_unlock(&xr_usb_serial_table_lock); + + return minor; +} + +/* Release the minor number associated with 'xr_usb_serial'. */ +static void xr_usb_serial_release_minor(struct xr_usb_serial *xr_usb_serial) +{ + mutex_lock(&xr_usb_serial_table_lock); + xr_usb_serial_table[xr_usb_serial->minor] = NULL; + mutex_unlock(&xr_usb_serial_table_lock); +} + +/* + * Functions for XR_USB_SERIAL control messages. + */ + +static int xr_usb_serial_ctrl_msg(struct xr_usb_serial *xr_usb_serial, int request, int value, + void *buf, int len) +{ + int retval = usb_control_msg(xr_usb_serial->dev, usb_sndctrlpipe(xr_usb_serial->dev, 0), + request, USB_RT_XR_USB_SERIAL, value, + xr_usb_serial->control->altsetting[0].desc.bInterfaceNumber, + buf, len, 5000); + dev_dbg(&xr_usb_serial->control->dev, + "%s - rq 0x%02x, val %#x, len %#x, result %d\n", + __func__, request, value, len, retval); + return retval < 0 ? retval : 0; +} + +#include "xr_usb_serial_hal.c" + +/* + * Write buffer management. + * All of these assume proper locks taken by the caller. + */ + +static int xr_usb_serial_wb_alloc(struct xr_usb_serial *xr_usb_serial) +{ + int i, wbn; + struct xr_usb_serial_wb *wb; + + wbn = 0; + i = 0; + for (;;) { + wb = &xr_usb_serial->wb[wbn]; + if (!wb->use) { + wb->use = 1; + return wbn; + } + wbn = (wbn + 1) % XR_USB_SERIAL_NW; + if (++i >= XR_USB_SERIAL_NW) + return -1; + } +} + +static int xr_usb_serial_wb_is_avail(struct xr_usb_serial *xr_usb_serial) +{ + int i, n; + unsigned long flags; + + n = XR_USB_SERIAL_NW; + spin_lock_irqsave(&xr_usb_serial->write_lock, flags); + for (i = 0; i < XR_USB_SERIAL_NW; i++) + n -= xr_usb_serial->wb[i].use; + spin_unlock_irqrestore(&xr_usb_serial->write_lock, flags); + return n; +} + +/* + * Finish write. Caller must hold xr_usb_serial->write_lock + */ +static void xr_usb_serial_write_done(struct xr_usb_serial *xr_usb_serial, struct xr_usb_serial_wb *wb) +{ + wb->use = 0; + xr_usb_serial->transmitting--; + usb_autopm_put_interface_async(xr_usb_serial->control); +} + +/* + * Poke write. + * + * the caller is responsible for locking + */ + +static int xr_usb_serial_start_wb(struct xr_usb_serial *xr_usb_serial, struct xr_usb_serial_wb *wb) +{ + int rc; + + xr_usb_serial->transmitting++; + + wb->urb->transfer_buffer = wb->buf; + wb->urb->transfer_dma = wb->dmah; + wb->urb->transfer_buffer_length = wb->len; + wb->urb->dev = xr_usb_serial->dev; + + rc = usb_submit_urb(wb->urb, GFP_ATOMIC); + if (rc < 0) { + dev_err(&xr_usb_serial->data->dev, + "%s - usb_submit_urb(write bulk) failed: %d\n", + __func__, rc); + xr_usb_serial_write_done(xr_usb_serial, wb); + } + return rc; +} + +/* + * attributes exported through sysfs + */ +static ssize_t show_caps +(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct xr_usb_serial *xr_usb_serial = usb_get_intfdata(intf); + + return sprintf(buf, "%d", xr_usb_serial->ctrl_caps); +} +static DEVICE_ATTR(bmCapabilities, S_IRUGO, show_caps, NULL); + +static ssize_t show_country_codes +(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct xr_usb_serial *xr_usb_serial = usb_get_intfdata(intf); + + memcpy(buf, xr_usb_serial->country_codes, xr_usb_serial->country_code_size); + return xr_usb_serial->country_code_size; +} + +static DEVICE_ATTR(wCountryCodes, S_IRUGO, show_country_codes, NULL); + +static ssize_t show_country_rel_date +(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct xr_usb_serial *xr_usb_serial = usb_get_intfdata(intf); + + return sprintf(buf, "%d", xr_usb_serial->country_rel_date); +} + +static DEVICE_ATTR(iCountryCodeRelDate, S_IRUGO, show_country_rel_date, NULL); +/* + * Interrupt handlers for various XR_USB_SERIAL device responses + */ + +/* control interface reports status changes with "interrupt" transfers */ +static void xr_usb_serial_ctrl_irq(struct urb *urb) +{ + struct xr_usb_serial *xr_usb_serial = urb->context; + struct usb_cdc_notification *dr = urb->transfer_buffer; +#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 9, 0) +#else + struct tty_struct *tty; +#endif + unsigned char *data; + int newctrl; + int retval; + int status = urb->status; + int i; + unsigned char *p; + + switch (status) { + case 0: + p = (unsigned char *)(urb->transfer_buffer); + for(i=0;iactual_length;i++) + { + dev_dbg(&xr_usb_serial->control->dev,"0x%02x\n",p[i]); + } + /* success */ + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dev_dbg(&xr_usb_serial->control->dev, + "%s - urb shutting down with status: %d\n", + __func__, status); + return; + default: + dev_dbg(&xr_usb_serial->control->dev, + "%s - nonzero urb status received: %d\n", + __func__, status); + goto exit; + } + + usb_mark_last_busy(xr_usb_serial->dev); + + data = (unsigned char *)(dr + 1); + switch (dr->bNotificationType) { + case USB_CDC_NOTIFY_NETWORK_CONNECTION: + dev_dbg(&xr_usb_serial->control->dev, "%s - network connection: %d\n", + __func__, dr->wValue); + break; + + case USB_CDC_NOTIFY_SERIAL_STATE: +#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 9, 0) + newctrl = get_unaligned_le16(data); + if (!xr_usb_serial->clocal && (xr_usb_serial->ctrlin & ~newctrl & XR_USB_SERIAL_CTRL_DCD)) { + dev_dbg(&xr_usb_serial->control->dev, "%s - calling hangup\n", + __func__); + tty_port_tty_hangup(&xr_usb_serial->port, false); + } +#else + tty = tty_port_tty_get(&xr_usb_serial->port); + newctrl = get_unaligned_le16(data); + if (tty) + { + if (!xr_usb_serial->clocal && + (xr_usb_serial->ctrlin & ~newctrl & XR_USB_SERIAL_CTRL_DCD)) { + dev_dbg(&xr_usb_serial->control->dev, + "%s - calling hangup\n", __func__); + tty_hangup(tty); + } + tty_kref_put(tty); + } +#endif + xr_usb_serial->ctrlin = newctrl; + + dev_dbg(&xr_usb_serial->control->dev, + "%s - input control lines: dcd%c dsr%c break%c " + "ring%c framing%c parity%c overrun%c\n", + __func__, + xr_usb_serial->ctrlin & XR_USB_SERIAL_CTRL_DCD ? '+' : '-', + xr_usb_serial->ctrlin & XR_USB_SERIAL_CTRL_DSR ? '+' : '-', + xr_usb_serial->ctrlin & XR_USB_SERIAL_CTRL_BRK ? '+' : '-', + xr_usb_serial->ctrlin & XR_USB_SERIAL_CTRL_RI ? '+' : '-', + xr_usb_serial->ctrlin & XR_USB_SERIAL_CTRL_FRAMING ? '+' : '-', + xr_usb_serial->ctrlin & XR_USB_SERIAL_CTRL_PARITY ? '+' : '-', + xr_usb_serial->ctrlin & XR_USB_SERIAL_CTRL_OVERRUN ? '+' : '-'); + break; + + default: + dev_dbg(&xr_usb_serial->control->dev, + "%s - unknown notification %d received: index %d " + "len %d data0 %d data1 %d\n", + __func__, + dr->bNotificationType, dr->wIndex, + dr->wLength, data[0], data[1]); + break; + } +exit: + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (retval) + dev_err(&xr_usb_serial->control->dev, "%s - usb_submit_urb failed: %d\n", + __func__, retval); +} + +static int xr_usb_serial_submit_read_urb(struct xr_usb_serial *xr_usb_serial, int index, gfp_t mem_flags) +{ + int res; + + if (!test_and_clear_bit(index, &xr_usb_serial->read_urbs_free)) + return 0; + + dev_vdbg(&xr_usb_serial->data->dev, "%s - urb %d\n", __func__, index); + + res = usb_submit_urb(xr_usb_serial->read_urbs[index], mem_flags); + if (res) { + if (res != -EPERM) { + dev_err(&xr_usb_serial->data->dev, + "%s - usb_submit_urb failed: %d\n", + __func__, res); + } + set_bit(index, &xr_usb_serial->read_urbs_free); + return res; + } + + return 0; +} + +static int xr_usb_serial_submit_read_urbs(struct xr_usb_serial *xr_usb_serial, gfp_t mem_flags) +{ + int res; + int i; + + for (i = 0; i < xr_usb_serial->rx_buflimit; ++i) { + res = xr_usb_serial_submit_read_urb(xr_usb_serial, i, mem_flags); + if (res) + return res; + } + + return 0; +} +static void xr_usb_serial_process_read_urb(struct xr_usb_serial *xr_usb_serial, struct urb *urb) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 9, 0) +#else + struct tty_struct *tty; +#endif + int preciseflags = xr_usb_serial->preciseflags; + int have_extra_byte; + int length; + + if (!urb->actual_length) + return; + + if (preciseflags) + { + char *dp = urb->transfer_buffer; + int i, ch, ch_flags; + + length = urb->actual_length; + length = length + (xr_usb_serial->have_extra_byte ? 1 : 0); + have_extra_byte = (preciseflags && (length & 1)); + length = (preciseflags) ? (length / 2) : length; + for (i = 0; i < length; ++i) + { + char tty_flag; + if (i == 0) + { + if (xr_usb_serial->have_extra_byte) + { + ch = xr_usb_serial->extra_byte; + } + else + { + ch = *dp++; + } + } + else + { + ch = *dp++; + } + ch_flags = *dp++; + if (ch_flags & RAMCTL_BUFFER_PARITY) + tty_flag = TTY_PARITY; + else if (ch_flags & RAMCTL_BUFFER_BREAK) + tty_flag = TTY_BREAK; + else if (ch_flags & RAMCTL_BUFFER_FRAME) + tty_flag = TTY_FRAME; + else if (ch_flags & RAMCTL_BUFFER_OVERRUN) + tty_flag = TTY_OVERRUN; + else + tty_flag = TTY_NORMAL; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) + tty_insert_flip_char(&xr_usb_serial->port, ch, tty_flag); + tty_flip_buffer_push(&xr_usb_serial->port); +#else + tty = tty_port_tty_get(&xr_usb_serial->port); + if (!tty) + return; + tty_insert_flip_char(&xr_usb_serial->port, ch, tty_flag); + tty_flip_buffer_push(tty); + tty_kref_put(tty); +#endif + } + } + else + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) + tty_insert_flip_string(&xr_usb_serial->port, urb->transfer_buffer, + urb->actual_length); + tty_flip_buffer_push(&xr_usb_serial->port); +#else + tty = tty_port_tty_get(&xr_usb_serial->port); + if (!tty) + return; + tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length); + tty_flip_buffer_push(tty); + tty_kref_put(tty); +#endif + } +} + +static void xr_usb_serial_read_bulk_callback(struct urb *urb) +{ + struct xr_usb_serial_rb *rb = urb->context; + struct xr_usb_serial *xr_usb_serial = rb->instance; + unsigned long flags; + + dev_vdbg(&xr_usb_serial->data->dev, "%s - urb %d, len %d\n", __func__, + rb->index, urb->actual_length); + set_bit(rb->index, &xr_usb_serial->read_urbs_free); + + if (!xr_usb_serial->dev) { + dev_dbg(&xr_usb_serial->data->dev, "%s - disconnected\n", __func__); + return; + } + usb_mark_last_busy(xr_usb_serial->dev); + + if (urb->status) { + dev_dbg(&xr_usb_serial->data->dev, "%s - non-zero urb status: %d\n", + __func__, urb->status); + //return; + } + xr_usb_serial_process_read_urb(xr_usb_serial, urb); + + /* throttle device if requested by tty */ + spin_lock_irqsave(&xr_usb_serial->read_lock, flags); + xr_usb_serial->throttled = xr_usb_serial->throttle_req; + if (!xr_usb_serial->throttled && !xr_usb_serial->susp_count) { + spin_unlock_irqrestore(&xr_usb_serial->read_lock, flags); + xr_usb_serial_submit_read_urb(xr_usb_serial, rb->index, GFP_ATOMIC); + } else { + spin_unlock_irqrestore(&xr_usb_serial->read_lock, flags); + } +} + +/* data interface wrote those outgoing bytes */ +static void xr_usb_serial_write_bulk(struct urb *urb) +{ + struct xr_usb_serial_wb *wb = urb->context; + struct xr_usb_serial *xr_usb_serial = wb->instance; + unsigned long flags; + + if (urb->status || (urb->actual_length != urb->transfer_buffer_length)) + dev_vdbg(&xr_usb_serial->data->dev, "%s - len %d/%d, status %d\n", + __func__, + urb->actual_length, + urb->transfer_buffer_length, + urb->status); + + spin_lock_irqsave(&xr_usb_serial->write_lock, flags); + xr_usb_serial_write_done(xr_usb_serial, wb); + spin_unlock_irqrestore(&xr_usb_serial->write_lock, flags); + schedule_work(&xr_usb_serial->work); +} + +static void xr_usb_serial_softint(struct work_struct *work) +{ + struct xr_usb_serial *xr_usb_serial = container_of(work, struct xr_usb_serial, work); +#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 9, 0) +#else + struct tty_struct *tty; +#endif + + dev_vdbg(&xr_usb_serial->data->dev, "%s\n", __func__); +#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 9, 0) + tty_port_tty_wakeup(&xr_usb_serial->port); +#else + tty = tty_port_tty_get(&xr_usb_serial->port); + if (!tty) + return; + tty_wakeup(tty); + tty_kref_put(tty); +#endif +} + +/* + * TTY handlers + */ + +static int xr_usb_serial_tty_install(struct tty_driver *driver, struct tty_struct *tty) +{ + struct xr_usb_serial *xr_usb_serial; + int retval; + + dev_dbg(tty->dev, "%s\n", __func__); + + xr_usb_serial = xr_usb_serial_get_by_index(tty->index); + if (!xr_usb_serial) + return -ENODEV; + + retval = tty_standard_install(driver, tty); + if (retval) + goto error_init_termios; + + tty->driver_data = xr_usb_serial; + + return 0; + +error_init_termios: + tty_port_put(&xr_usb_serial->port); + return retval; +} + +static int xr_usb_serial_tty_open(struct tty_struct *tty, struct file *filp) +{ + struct xr_usb_serial *xr_usb_serial = tty->driver_data; + int result; + + result = xr_usb_serial_fifo_reset(xr_usb_serial); + dev_dbg(tty->dev, "%s\n", __func__); + + return tty_port_open(&xr_usb_serial->port, tty, filp); +} + +static int xr_usb_serial_port_activate(struct tty_port *port, struct tty_struct *tty) +{ + struct xr_usb_serial *xr_usb_serial = container_of(port, struct xr_usb_serial, port); + int retval = -ENODEV; + + dev_dbg(&xr_usb_serial->control->dev, "%s\n", __func__); + + mutex_lock(&xr_usb_serial->mutex); + if (xr_usb_serial->disconnected) + goto disconnected; + + retval = usb_autopm_get_interface(xr_usb_serial->control); + if (retval) + goto error_get_interface; + + /* + * FIXME: Why do we need this? Allocating 64K of physically contiguous + * memory is really nasty... + */ + set_bit(TTY_NO_WRITE_SPLIT, &tty->flags); + xr_usb_serial->control->needs_remote_wakeup = 1; + + xr_usb_serial->ctrlurb->dev = xr_usb_serial->dev; + if (usb_submit_urb(xr_usb_serial->ctrlurb, GFP_KERNEL)) { + dev_err(&xr_usb_serial->control->dev, + "%s - usb_submit_urb(ctrl irq) failed\n", __func__); + goto error_submit_urb; + } + + xr_usb_serial->ctrlout = XR_USB_SERIAL_CTRL_DTR | XR_USB_SERIAL_CTRL_RTS; + if (xr_usb_serial_set_control(xr_usb_serial, xr_usb_serial->ctrlout) < 0 && + (xr_usb_serial->ctrl_caps & USB_CDC_CAP_LINE)) + goto error_set_control; + + usb_autopm_put_interface(xr_usb_serial->control); + + /* + * Unthrottle device in case the TTY was closed while throttled. + */ + spin_lock_irq(&xr_usb_serial->read_lock); + xr_usb_serial->throttled = 0; + xr_usb_serial->throttle_req = 0; + spin_unlock_irq(&xr_usb_serial->read_lock); + + if (xr_usb_serial_submit_read_urbs(xr_usb_serial, GFP_KERNEL)) + goto error_submit_read_urbs; + + mutex_unlock(&xr_usb_serial->mutex); + + return 0; + +error_submit_read_urbs: + xr_usb_serial->ctrlout = 0; + xr_usb_serial_set_control(xr_usb_serial, xr_usb_serial->ctrlout); +error_set_control: + usb_kill_urb(xr_usb_serial->ctrlurb); +error_submit_urb: + usb_autopm_put_interface(xr_usb_serial->control); +error_get_interface: +disconnected: + mutex_unlock(&xr_usb_serial->mutex); + return retval; +} + +static void xr_usb_serial_port_destruct(struct tty_port *port) +{ + struct xr_usb_serial *xr_usb_serial = container_of(port, struct xr_usb_serial, port); + + dev_dbg(&xr_usb_serial->control->dev, "%s\n", __func__); +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0) + tty_unregister_device(xr_usb_serial_tty_driver, xr_usb_serial->minor); +#endif +#ifdef CONFIG_GPIOLIB + if (xr_usb_serial->rv_gpio_created == 0) + gpiochip_remove(&xr_usb_serial->xr_gpio); +#endif + xr_usb_serial_release_minor(xr_usb_serial); + usb_put_intf(xr_usb_serial->control); + kfree(xr_usb_serial->country_codes); + kfree(xr_usb_serial); +} + +static void xr_usb_serial_port_shutdown(struct tty_port *port) +{ + struct xr_usb_serial *xr_usb_serial = container_of(port, struct xr_usb_serial, port); + int i; + + dev_dbg(&xr_usb_serial->control->dev, "%s\n", __func__); + + mutex_lock(&xr_usb_serial->mutex); + if (!xr_usb_serial->disconnected) { + usb_autopm_get_interface(xr_usb_serial->control); + xr_usb_serial_set_control(xr_usb_serial, xr_usb_serial->ctrlout = 0); + usb_kill_urb(xr_usb_serial->ctrlurb); + for (i = 0; i < XR_USB_SERIAL_NW; i++) + usb_kill_urb(xr_usb_serial->wb[i].urb); + for (i = 0; i < xr_usb_serial->rx_buflimit; i++) + usb_kill_urb(xr_usb_serial->read_urbs[i]); + xr_usb_serial->control->needs_remote_wakeup = 0; + usb_autopm_put_interface(xr_usb_serial->control); + } + mutex_unlock(&xr_usb_serial->mutex); +} + +static void xr_usb_serial_tty_cleanup(struct tty_struct *tty) +{ + struct xr_usb_serial *xr_usb_serial = tty->driver_data; + dev_dbg(&xr_usb_serial->control->dev, "%s\n", __func__); + tty_port_put(&xr_usb_serial->port); +} + +static void xr_usb_serial_tty_hangup(struct tty_struct *tty) +{ + struct xr_usb_serial *xr_usb_serial = tty->driver_data; + dev_dbg(&xr_usb_serial->control->dev, "%s\n", __func__); + tty_port_hangup(&xr_usb_serial->port); +} + +static void xr_usb_serial_tty_close(struct tty_struct *tty, struct file *filp) +{ + struct xr_usb_serial *xr_usb_serial = tty->driver_data; + dev_dbg(&xr_usb_serial->control->dev, "%s\n", __func__); + tty_port_close(&xr_usb_serial->port, tty, filp); +} + +static int xr_usb_serial_tty_write(struct tty_struct *tty, + const unsigned char *buf, int count) +{ + struct xr_usb_serial *xr_usb_serial = tty->driver_data; + int stat; + unsigned long flags; + int wbn; + struct xr_usb_serial_wb *wb; + + if (!count) + return 0; + + //dev_vdbg(&xr_usb_serial->data->dev, "%s - count %d\n", __func__, count); + + spin_lock_irqsave(&xr_usb_serial->write_lock, flags); + wbn = xr_usb_serial_wb_alloc(xr_usb_serial); + if (wbn < 0) { + spin_unlock_irqrestore(&xr_usb_serial->write_lock, flags); + return 0; + } + wb = &xr_usb_serial->wb[wbn]; + + if (!xr_usb_serial->dev) { + wb->use = 0; + spin_unlock_irqrestore(&xr_usb_serial->write_lock, flags); + return -ENODEV; + } + + count = (count > xr_usb_serial->writesize) ? xr_usb_serial->writesize : count; + //dev_vdbg(&xr_usb_serial->data->dev, "%s - write %d\n", __func__, count); + memcpy(wb->buf, buf, count); + wb->len = count; + + usb_autopm_get_interface_async(xr_usb_serial->control); + if (xr_usb_serial->susp_count) { + if (!xr_usb_serial->delayed_wb) + xr_usb_serial->delayed_wb = wb; + else + usb_autopm_put_interface_async(xr_usb_serial->control); + spin_unlock_irqrestore(&xr_usb_serial->write_lock, flags); + return count; /* A white lie */ + } + usb_mark_last_busy(xr_usb_serial->dev); + + stat = xr_usb_serial_start_wb(xr_usb_serial, wb); + spin_unlock_irqrestore(&xr_usb_serial->write_lock, flags); + + if (stat < 0) + return stat; + return count; +} + +static int xr_usb_serial_tty_write_room(struct tty_struct *tty) +{ + struct xr_usb_serial *xr_usb_serial = tty->driver_data; + /* + * Do not let the line discipline to know that we have a reserve, + * or it might get too enthusiastic. + */ + return xr_usb_serial_wb_is_avail(xr_usb_serial) ? xr_usb_serial->writesize : 0; +} + +static int xr_usb_serial_tty_chars_in_buffer(struct tty_struct *tty) +{ + struct xr_usb_serial *xr_usb_serial = tty->driver_data; + /* + * if the device was unplugged then any remaining characters fell out + * of the connector ;) + */ + if (xr_usb_serial->disconnected) + return 0; + /* + * This is inaccurate (overcounts), but it works. + */ + return (XR_USB_SERIAL_NW - xr_usb_serial_wb_is_avail(xr_usb_serial)) * xr_usb_serial->writesize; +} + +static void xr_usb_serial_tty_throttle(struct tty_struct *tty) +{ + struct xr_usb_serial *xr_usb_serial = tty->driver_data; + + spin_lock_irq(&xr_usb_serial->read_lock); + xr_usb_serial->throttle_req = 1; + spin_unlock_irq(&xr_usb_serial->read_lock); +} + +static void xr_usb_serial_tty_unthrottle(struct tty_struct *tty) +{ + struct xr_usb_serial *xr_usb_serial = tty->driver_data; + unsigned int was_throttled; + + spin_lock_irq(&xr_usb_serial->read_lock); + was_throttled = xr_usb_serial->throttled; + xr_usb_serial->throttled = 0; + xr_usb_serial->throttle_req = 0; + spin_unlock_irq(&xr_usb_serial->read_lock); + + if (was_throttled) + xr_usb_serial_submit_read_urbs(xr_usb_serial, GFP_KERNEL); +} + +static int xr_usb_serial_tty_break_ctl(struct tty_struct *tty, int state) +{ + struct xr_usb_serial *xr_usb_serial = tty->driver_data; + int retval; + + retval = xr_usb_serial_send_break(xr_usb_serial, state ? 0xffff : 0); + if (retval < 0) + dev_err(&xr_usb_serial->control->dev, "%s - send break failed\n", + __func__); + return retval; +} + +static int xr_usb_serial_tty_tiocmget(struct tty_struct *tty) +{ + struct xr_usb_serial *xr_usb_serial = tty->driver_data; + //dev_dbg(&xr_usb_serial->control->dev, "xr_usb_serial_tty_tiocmget\n"); + return xr_usb_serial_tiocmget(xr_usb_serial); +} + +static int xr_usb_serial_tty_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + struct xr_usb_serial *xr_usb_serial = tty->driver_data; + //dev_dbg(&xr_usb_serial->control->dev, "xr_usb_serial_tty_tiocmset set=0x%x clear=0x%x\n",set,clear); + return xr_usb_serial_tiocmset(xr_usb_serial,set,clear); +} + +static int get_serial_info(struct xr_usb_serial *xr_usb_serial, struct serial_struct __user *info) +{ + struct serial_struct tmp; + + if (!info) + return -EINVAL; + + memset(&tmp, 0, sizeof(tmp)); + tmp.flags = ASYNC_LOW_LATENCY; + tmp.xmit_fifo_size = xr_usb_serial->writesize; + tmp.baud_base = le32_to_cpu(xr_usb_serial->line.dwDTERate); + tmp.close_delay = xr_usb_serial->port.close_delay / 10; + tmp.closing_wait = xr_usb_serial->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? + ASYNC_CLOSING_WAIT_NONE : + xr_usb_serial->port.closing_wait / 10; + + if (copy_to_user(info, &tmp, sizeof(tmp))) + return -EFAULT; + else + return 0; +} + +static int set_serial_info(struct xr_usb_serial *xr_usb_serial, + struct serial_struct __user *newinfo) +{ + struct serial_struct new_serial; + unsigned int closing_wait, close_delay; + int retval = 0; + + if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) + return -EFAULT; + + close_delay = new_serial.close_delay * 10; + closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? + ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10; + + mutex_lock(&xr_usb_serial->port.mutex); + + if (!capable(CAP_SYS_ADMIN)) { + if ((close_delay != xr_usb_serial->port.close_delay) || + (closing_wait != xr_usb_serial->port.closing_wait)) + retval = -EPERM; + else + retval = -EOPNOTSUPP; + } else { + xr_usb_serial->port.close_delay = close_delay; + xr_usb_serial->port.closing_wait = closing_wait; + } + + mutex_unlock(&xr_usb_serial->port.mutex); + return retval; +} + +static int xr_usb_serial_tty_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + struct xr_usb_serial *xr_usb_serial = tty->driver_data; + int rv = -ENOIOCTLCMD; + unsigned int channel, reg, val,preciseflags; + int baud_rate = 0; + struct usb_cdc_line_coding newline; + short *data; + switch (cmd) { + case TIOCGSERIAL: /* gets serial port data */ + rv = get_serial_info(xr_usb_serial, (struct serial_struct __user *) arg); + break; + case TIOCSSERIAL: + rv = set_serial_info(xr_usb_serial, (struct serial_struct __user *) arg); + break; + case XR_USB_SERIAL_GET_REG: + if (get_user(channel, (int __user *)arg)) + return -EFAULT; + if (get_user(reg, (int __user *)(arg + sizeof(int)))) + return -EFAULT; + + data = kmalloc(2, GFP_KERNEL); + if (data == NULL) { + dev_err(&xr_usb_serial->control->dev, "%s - Cannot allocate USB buffer.\n", __func__); + return -ENOMEM; + } + + if (channel == -1) + { + rv = xr_usb_serial_get_reg(xr_usb_serial,reg, data); + } + else + { + rv = xr_usb_serial_get_reg_ext(xr_usb_serial,channel,reg, data); + } + if (rv < 0) + { + dev_err(&xr_usb_serial->control->dev, "Cannot get register (%d)\n", rv); + kfree(data); + return -EFAULT; + } + if (put_user(le16_to_cpu(*data), (int __user *)(arg + 2 * sizeof(int)))) + { + dev_err(&xr_usb_serial->control->dev, "Cannot put user result\n"); + kfree(data); + return -EFAULT; + } + rv = 0; + kfree(data); + break; + case XR_USB_SERIAL_SET_REG: + if (get_user(channel, (int __user *)arg)) + return -EFAULT; + if (get_user(reg, (int __user *)(arg + sizeof(int)))) + return -EFAULT; + if (get_user(val, (int __user *)(arg + 2 * sizeof(int)))) + return -EFAULT; + + if (channel == -1) + { + rv = xr_usb_serial_set_reg(xr_usb_serial,reg, val); + } + else + { + rv = xr_usb_serial_set_reg_ext(xr_usb_serial,channel,reg, val); + } + if (rv < 0) + return -EFAULT; + rv = 0; + break; + case XR_USB_SERIAL_LOOPBACK: + if (get_user(channel, (int __user *)arg)) + return -EFAULT; + if (channel == -1) + channel = xr_usb_serial->channel; + rv = xr_usb_serial_set_loopback(xr_usb_serial,channel); + if (rv < 0) + return -EFAULT; + rv = 0; + break; + case XR_USB_SERIAL_SET_GPIO_MODE_REG: + xr_usb_serial_disable(xr_usb_serial); + if (get_user(channel, (int __user *)arg)) + return -EFAULT; + if (get_user(val, (int __user *)(arg + sizeof(int)))) + return -EFAULT; + if (channel == -1) + { + //block = portdata->block; + rv = xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_gpio_mode_addr, val); + } + else + { + rv = xr_usb_serial_set_reg_ext(xr_usb_serial,channel,xr_usb_serial->reg_map.uart_gpio_mode_addr, val); + } + + dev_dbg(&xr_usb_serial->control->dev, "XR_USB_SERIAL_SET_GPIO_MODE_REG 0x%x val:0x%x \n", xr_usb_serial->reg_map.uart_gpio_mode_addr,val); + xr_usb_serial_enable(xr_usb_serial); + if (rv < 0) + return -EFAULT; + break; + case XR_USB_SERIAL_GET_GPIO_MODE_REG: + xr_usb_serial_disable(xr_usb_serial); + if (get_user(channel, (int __user *)arg)) + return -EFAULT; + + data = kmalloc(2, GFP_KERNEL); + if (data == NULL) { + dev_err(&xr_usb_serial->control->dev, "%s - Cannot allocate USB buffer.\n", __func__); + return -ENOMEM; + } + + if (channel == -1) + { + rv = xr_usb_serial_get_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_gpio_mode_addr, data); + } + else + { + rv = xr_usb_serial_get_reg_ext(xr_usb_serial,channel,xr_usb_serial->reg_map.uart_gpio_mode_addr,data); + } + + xr_usb_serial_enable(xr_usb_serial); + + dev_dbg(&xr_usb_serial->control->dev, "XR_USB_SERIAL_GET_GPIO_MODE_REG 0x%x val:0x%x \n", xr_usb_serial->reg_map.uart_gpio_mode_addr,*data); + + if (rv < 0 ) { + dev_err(&xr_usb_serial->control->dev, "Cannot get register (%d) channel=%d \n", rv,channel); + kfree(data); + return -EFAULT; + } + + if (put_user(data[0], (int __user *)(arg + sizeof(int)))) { + dev_err(&xr_usb_serial->control->dev, "Cannot put user result\n"); + kfree(data); + return -EFAULT; + } + + kfree(data); + break; + case XRIOC_SET_ANY_BAUD_RATE: + if (get_user(baud_rate, (int __user *)arg)) { + dev_dbg(&xr_usb_serial->control->dev, "get_user errot \n"); + return -EFAULT; + } + xr_usb_serial->line.dwDTERate = baud_rate; + memcpy(&newline,&(xr_usb_serial->line),sizeof(struct usb_cdc_line_coding)); + xr_usb_serial_disable(xr_usb_serial); + rv = xr_usb_serial_set_line(xr_usb_serial,&newline); + xr_usb_serial_enable(xr_usb_serial); + dev_dbg(&xr_usb_serial->control->dev, "XRIOC_SET_ANY_BAUD_RATE set baud_rate:%d ret=%d\n", baud_rate,rv); + break; + case XRIOC_SET_PRECISE_FLAGS: + preciseflags = arg; + dev_dbg(&xr_usb_serial->control->dev, "%s VIOC_SET_PRECISE_FLAGS %d\n", __func__, preciseflags); + xr_usb_serial_disable(xr_usb_serial); + if (preciseflags) + { + xr_usb_serial->preciseflags = 1; + } + else + { + xr_usb_serial->preciseflags = 0; + } + xr_usb_serial_set_wide_mode(xr_usb_serial,xr_usb_serial->preciseflags); + xr_usb_serial_enable(xr_usb_serial); + break; + } + + return rv; +} + +#ifdef CONFIG_COMPAT +static long xr_usb_serial_tty_compat_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + void __user *up = compat_ptr(arg); + + switch (cmd) { + case TIOCGSERIAL: /* gets serial port data */ + case TIOCSSERIAL: + case XR_USB_SERIAL_GET_REG: + case XR_USB_SERIAL_SET_REG: + case XR_USB_SERIAL_LOOPBACK: + case XR_USB_SERIAL_SET_GPIO_MODE_REG: + case XR_USB_SERIAL_GET_GPIO_MODE_REG: + case XRIOC_SET_ANY_BAUD_RATE: + case XRIOC_SET_PRECISE_FLAGS: + return xr_usb_serial_tty_ioctl(tty, cmd, arg); + + /* + * the rest has a compatible data structure behind arg, + * but we have to convert it to a proper 64 bit pointer. + */ + default: + return xr_usb_serial_tty_ioctl(tty, cmd, (unsigned long)up); + } +} +#endif + +static void xr_usb_serial_tty_set_termios(struct tty_struct *tty, + struct ktermios *termios_old) +{ + struct xr_usb_serial *xr_usb_serial = tty->driver_data; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0) + struct ktermios *termios = tty->termios; +#else + struct ktermios *termios = &tty->termios; +#endif + unsigned int cflag = termios->c_cflag; + struct usb_cdc_line_coding newline; + int newctrl = xr_usb_serial->ctrlout; + xr_usb_serial_disable(xr_usb_serial); + newline.dwDTERate = cpu_to_le32(tty_get_baud_rate(tty)); + newline.bCharFormat = termios->c_cflag & CSTOPB ? 1 : 0; + newline.bParityType = termios->c_cflag & PARENB ? + (termios->c_cflag & PARODD ? 1 : 2) + + (termios->c_cflag & CMSPAR ? 2 : 0) : 0; + xr_usb_serial->trans9 = 0; + switch (termios->c_cflag & CSIZE) { + case CS5:/*using CS5 replace of the 9 bit data mode*/ + newline.bDataBits = 9; + xr_usb_serial->trans9 =1; + break; + case CS6: + newline.bDataBits = 6; + break; + case CS7: + newline.bDataBits = 7; + break; + case CS8: + default: + newline.bDataBits = 8; + break; + } + /* FIXME: Needs to clear unsupported bits in the termios */ + xr_usb_serial->clocal = ((termios->c_cflag & CLOCAL) != 0); + + if (!newline.dwDTERate) { + newline.dwDTERate = xr_usb_serial->line.dwDTERate; + newctrl &= ~XR_USB_SERIAL_CTRL_DTR; + } else + newctrl |= XR_USB_SERIAL_CTRL_DTR; + + if (newctrl != xr_usb_serial->ctrlout) + xr_usb_serial_set_control(xr_usb_serial, xr_usb_serial->ctrlout = newctrl); + + if((cflag & CRTSCTS) != (termios_old->c_cflag & CRTSCTS)) + { + /* Set the serial flow mode only when needed */ + xr_usb_serial_set_flow_mode(xr_usb_serial,tty,cflag); + } + + if (xr_usb_serial->trans9) + { + /* Turn on wide mode if we're 9-bit transparent. */ + xr_usb_serial_set_wide_mode(xr_usb_serial,1); + } + else if (!xr_usb_serial->preciseflags) + { + xr_usb_serial_set_wide_mode(xr_usb_serial,0); + } + + if (memcmp(&xr_usb_serial->line, &newline, sizeof newline)) + { + memcpy(&xr_usb_serial->line, &newline, sizeof newline); + dev_dbg(&xr_usb_serial->control->dev, "%s - set line: %d %d %d %d\n", + __func__, + le32_to_cpu(newline.dwDTERate), + newline.bCharFormat, newline.bParityType, + newline.bDataBits); + xr_usb_serial_set_line(xr_usb_serial, &xr_usb_serial->line); + } + xr_usb_serial_enable(xr_usb_serial); +} + +static const struct tty_port_operations xr_usb_serial_port_ops = { + .shutdown = xr_usb_serial_port_shutdown, + .activate = xr_usb_serial_port_activate, + .destruct = xr_usb_serial_port_destruct, +}; + +/* + * USB probe and disconnect routines. + */ + +/* Little helpers: write/read buffers free */ +static void xr_usb_serial_write_buffers_free(struct xr_usb_serial *xr_usb_serial) +{ + int i; + struct xr_usb_serial_wb *wb; + struct usb_device *usb_dev = interface_to_usbdev(xr_usb_serial->control); + + for (wb = &xr_usb_serial->wb[0], i = 0; i < XR_USB_SERIAL_NW; i++, wb++) + usb_free_coherent(usb_dev, xr_usb_serial->writesize, wb->buf, wb->dmah); +} + +static void xr_usb_serial_read_buffers_free(struct xr_usb_serial *xr_usb_serial) +{ + struct usb_device *usb_dev = interface_to_usbdev(xr_usb_serial->control); + int i; + + for (i = 0; i < xr_usb_serial->rx_buflimit; i++) + usb_free_coherent(usb_dev, xr_usb_serial->readsize, + xr_usb_serial->read_buffers[i].base, xr_usb_serial->read_buffers[i].dma); +} + +/* Little helper: write buffers allocate */ +static int xr_usb_serial_write_buffers_alloc(struct xr_usb_serial *xr_usb_serial) +{ + int i; + struct xr_usb_serial_wb *wb; + + for (wb = &xr_usb_serial->wb[0], i = 0; i < XR_USB_SERIAL_NW; i++, wb++) { + wb->buf = usb_alloc_coherent(xr_usb_serial->dev, xr_usb_serial->writesize, GFP_KERNEL, + &wb->dmah); + if (!wb->buf) { + while (i != 0) { + --i; + --wb; + usb_free_coherent(xr_usb_serial->dev, xr_usb_serial->writesize, + wb->buf, wb->dmah); + } + return -ENOMEM; + } + } + return 0; +} + +#ifdef CONFIG_GPIOLIB +static int xr_usb_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct xr_usb_serial *xr_usb_serial = container_of(chip, struct xr_usb_serial, xr_gpio); + int rv; + short gpio_status; + + rv = xr_usb_serial_get_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_status_addr, + &gpio_status); + if (gpio_status&(1 << offset)) + return 1; + else + return 0; +} + +static void xr_usb_gpio_set(struct gpio_chip *chip, unsigned int offset, int val) +{ + struct xr_usb_serial *xr_usb_serial = container_of(chip, struct xr_usb_serial, xr_gpio); + int rv, tmp; + + tmp = 1 << offset; + if (val) + rv = xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_set_addr, tmp); + else + rv = xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_clr_addr, tmp); +} + +static int xr_usb_gpio_dir_input(struct gpio_chip *chip, unsigned int offset) +{ + int rv; + short dir_value; + struct xr_usb_serial *xr_usb_serial = container_of(chip, struct xr_usb_serial, xr_gpio); + + rv = xr_usb_serial_get_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_dir_addr, &dir_value); + dir_value &= ~(1 << offset); + rv = xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_dir_addr, (int)dir_value); + return 0; +} + +static int xr_usb_gpio_dir_output(struct gpio_chip *chip, + unsigned int offset, int val) +{ + int rv; + short tmp; + struct xr_usb_serial *xr_usb_serial = container_of(chip, struct xr_usb_serial, xr_gpio); + + rv = xr_usb_serial_get_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_dir_addr, &tmp); + printk ("gpio_dir_output, offset = %d\n", offset); + printk ("gpio_dir_output before set_reg = 0x%02x\n", tmp); + tmp |= (1 << offset); + rv = xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_dir_addr, (int)tmp); + rv = xr_usb_serial_get_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_dir_addr, &tmp); + printk ("gpio_dir_output after set_reg = 0x%02x\n", tmp); + + if (offset > 7) { + rv = xr_usb_serial_get_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_mode_addr, &tmp); + tmp &= ~(1 << offset); + rv = xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_mode_addr, + (int)tmp); + } + + return 0; +} +#endif + +static int xr_usb_serial_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_cdc_union_desc *union_header = NULL; + struct usb_cdc_country_functional_desc *cfd = NULL; + unsigned char *buffer = intf->altsetting->extra; + int buflen = intf->altsetting->extralen; + struct usb_interface *control_interface; + struct usb_interface *data_interface; + struct usb_endpoint_descriptor *epctrl = NULL; + struct usb_endpoint_descriptor *epread = NULL; + struct usb_endpoint_descriptor *epwrite = NULL; + struct usb_device *usb_dev = interface_to_usbdev(intf); + struct xr_usb_serial *xr_usb_serial; + int minor; + int ctrlsize, readsize; + u8 *buf; + u8 ac_management_function = 0; + u8 call_management_function = 0; + int call_interface_num = -1; + int data_interface_num = -1; + unsigned long quirks; + int num_rx_buf; + int i; + int combined_interfaces = 0; + struct device *tty_dev; + int rv = -ENOMEM; +#ifdef CONFIG_GPIOLIB + int gpiochip_base; +#endif + + /* normal quirks */ + quirks = (unsigned long)id->driver_info; + + if (quirks == IGNORE_DEVICE) + return -ENODEV; + + num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : XR_USB_SERIAL_NR; + + dev_dbg(&intf->dev, "USB_device_id idVendor:%04x, idProduct %04x\n",id->idVendor,id->idProduct); + + /* handle quirks deadly to normal probing*/ + if (quirks == NO_UNION_NORMAL) { + data_interface = usb_ifnum_to_if(usb_dev, 1); + control_interface = usb_ifnum_to_if(usb_dev, 0); + goto skip_normal_probe; + } + + /* normal probing*/ + if (!buffer) { + dev_err(&intf->dev, "Weird descriptor references\n"); + return -EINVAL; + } + + if (!buflen) { + if (intf->cur_altsetting->endpoint && + intf->cur_altsetting->endpoint->extralen && + intf->cur_altsetting->endpoint->extra) { + dev_dbg(&intf->dev, + "Seeking extra descriptors on endpoint\n"); + buflen = intf->cur_altsetting->endpoint->extralen; + buffer = intf->cur_altsetting->endpoint->extra; + } else { + dev_err(&intf->dev, + "Zero length descriptor references\n"); + return -EINVAL; + } + } + + while (buflen > 0) { + if (buffer[1] != USB_DT_CS_INTERFACE) { + dev_err(&intf->dev, "skipping garbage\n"); + goto next_desc; + } + + switch (buffer[2]) { + case USB_CDC_UNION_TYPE: /* we've found it */ + if (union_header) { + dev_err(&intf->dev, "More than one " + "union descriptor, skipping ...\n"); + goto next_desc; + } + union_header = (struct usb_cdc_union_desc *)buffer; + break; + case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/ + cfd = (struct usb_cdc_country_functional_desc *)buffer; + break; + case USB_CDC_HEADER_TYPE: /* maybe check version */ + break; /* for now we ignore it */ + case USB_CDC_ACM_TYPE: + ac_management_function = buffer[3]; + break; + case USB_CDC_CALL_MANAGEMENT_TYPE: + call_management_function = buffer[3]; + call_interface_num = buffer[4]; + if ((quirks & NOT_A_MODEM) == 0 && (call_management_function & 3) != 3) + dev_err(&intf->dev, "This device cannot do calls on its own. It is not a modem.\n"); + break; + default: + /* there are LOTS more CDC descriptors that + * could legitimately be found here. + */ + dev_dbg(&intf->dev, "Ignoring descriptor: " + "type %02x, length %d\n", + buffer[2], buffer[0]); + break; + } +next_desc: + buflen -= buffer[0]; + buffer += buffer[0]; + } + + if (!union_header) { + if (call_interface_num > 0) { + dev_dbg(&intf->dev, "No union descriptor, using call management descriptor\n"); + /* quirks for Droids MuIn LCD */ + if (quirks & NO_DATA_INTERFACE) + data_interface = usb_ifnum_to_if(usb_dev, 0); + else + data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num)); + control_interface = intf; + } else { + if (intf->cur_altsetting->desc.bNumEndpoints != 3) { + dev_dbg(&intf->dev,"No union descriptor, giving up\n"); + return -ENODEV; + } else { + dev_warn(&intf->dev,"No union descriptor, testing for castrated device\n"); + combined_interfaces = 1; + control_interface = data_interface = intf; + goto look_for_collapsed_interface; + } + } + } else { + control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0); + data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0)); + if (!control_interface || !data_interface) { + dev_dbg(&intf->dev, "no interfaces\n"); + return -ENODEV; + } + } + + if (data_interface_num != call_interface_num) + dev_dbg(&intf->dev, "Separate call control interface. That is not fully supported.\n"); + + if (control_interface == data_interface) { + /* some broken devices designed for windows work this way */ + dev_warn(&intf->dev,"Control and data interfaces are not separated!\n"); + combined_interfaces = 1; + /* a popular other OS doesn't use it */ + quirks |= NO_CAP_LINE; + if (data_interface->cur_altsetting->desc.bNumEndpoints != 3) { + dev_err(&intf->dev, "This needs exactly 3 endpoints\n"); + return -EINVAL; + } +look_for_collapsed_interface: + for (i = 0; i < 3; i++) { + struct usb_endpoint_descriptor *ep; + ep = &data_interface->cur_altsetting->endpoint[i].desc; + + if (usb_endpoint_is_int_in(ep)) + epctrl = ep; + else if (usb_endpoint_is_bulk_out(ep)) + epwrite = ep; + else if (usb_endpoint_is_bulk_in(ep)) + epread = ep; + else + return -EINVAL; + } + if (!epctrl || !epread || !epwrite) + return -ENODEV; + else + goto made_compressed_probe; + } + +skip_normal_probe: + + /*workaround for switched interfaces */ + if (data_interface->cur_altsetting->desc.bInterfaceClass + != CDC_DATA_INTERFACE_TYPE) { + if (control_interface->cur_altsetting->desc.bInterfaceClass + == CDC_DATA_INTERFACE_TYPE) { + struct usb_interface *t; + dev_dbg(&intf->dev, + "Your device has switched interfaces.\n"); + t = control_interface; + control_interface = data_interface; + data_interface = t; + } else { + return -EINVAL; + } + } + + /* Accept probe requests only for the control interface */ + if (!combined_interfaces && intf != control_interface) + return -ENODEV; + + if (!combined_interfaces && usb_interface_claimed(data_interface)) { + /* valid in this context */ + dev_dbg(&intf->dev, "The data interface isn't available\n"); + return -EBUSY; + } + + + if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 || + control_interface->cur_altsetting->desc.bNumEndpoints == 0) + return -EINVAL; + + epctrl = &control_interface->cur_altsetting->endpoint[0].desc; + epread = &data_interface->cur_altsetting->endpoint[0].desc; + epwrite = &data_interface->cur_altsetting->endpoint[1].desc; + + + /* workaround for switched endpoints */ + if (!usb_endpoint_dir_in(epread)) { + /* descriptors are swapped */ + struct usb_endpoint_descriptor *t; + dev_dbg(&intf->dev, + "The data interface has switched endpoints\n"); + t = epread; + epread = epwrite; + epwrite = t; + } +made_compressed_probe: + dev_dbg(&intf->dev, "interfaces are valid\n"); + + xr_usb_serial = kzalloc(sizeof(struct xr_usb_serial), GFP_KERNEL); + if (xr_usb_serial == NULL) { + dev_err(&intf->dev, "out of memory (xr_usb_serial kzalloc)\n"); + goto alloc_fail; + } + + minor = xr_usb_serial_alloc_minor(xr_usb_serial); + if (minor == XR_USB_SERIAL_TTY_MINORS) { + dev_err(&intf->dev, "no more free xr_usb_serial devices\n"); + kfree(xr_usb_serial); + return -ENODEV; + } + + ctrlsize = usb_endpoint_maxp(epctrl); + readsize = usb_endpoint_maxp(epread) * + (quirks == SINGLE_RX_URB ? 1 : 2); + xr_usb_serial->combined_interfaces = combined_interfaces; + xr_usb_serial->writesize = usb_endpoint_maxp(epwrite) * 20; + xr_usb_serial->control = control_interface; + xr_usb_serial->data = data_interface; + xr_usb_serial->minor = minor; + xr_usb_serial->dev = usb_dev; + xr_usb_serial->ctrl_caps = ac_management_function; + if (quirks & NO_CAP_LINE) + xr_usb_serial->ctrl_caps &= ~USB_CDC_CAP_LINE; + xr_usb_serial->ctrlsize = ctrlsize; + xr_usb_serial->readsize = readsize; + xr_usb_serial->rx_buflimit = num_rx_buf; + INIT_WORK(&xr_usb_serial->work, xr_usb_serial_softint); + spin_lock_init(&xr_usb_serial->write_lock); + spin_lock_init(&xr_usb_serial->read_lock); + mutex_init(&xr_usb_serial->mutex); + xr_usb_serial->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); + xr_usb_serial->is_int_ep = usb_endpoint_xfer_int(epread); + if (xr_usb_serial->is_int_ep) + xr_usb_serial->bInterval = epread->bInterval; + tty_port_init(&xr_usb_serial->port); + xr_usb_serial->port.ops = &xr_usb_serial_port_ops; + xr_usb_serial->DeviceVendor = id->idVendor; + xr_usb_serial->DeviceProduct = id->idProduct; +#if 0 + if((xr_usb_serial->DeviceProduct&0xfff0) == 0x1410) + {//map the serial port A B C D to blocknum 0 1 2 3 for the xr21v141x device + xr_usb_serial->channel = epwrite->bEndpointAddress - 1; + } + else if((xr_usb_serial->DeviceProduct&0xfff0) == 0x1420) + {//map the serial port A B C D to blocknum 0 2 4 6 for the xr21B142x device + xr_usb_serial->channel = (epwrite->bEndpointAddress - 4)*2; + } + else + { + xr_usb_serial->channel = epwrite->bEndpointAddress; + } +#else + xr_usb_serial->channel = epwrite->bEndpointAddress; + dev_dbg(&intf->dev, "epwrite->bEndpointAddress =%d\n",epwrite->bEndpointAddress); +#endif + buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &xr_usb_serial->ctrl_dma); + if (!buf) { + dev_err(&intf->dev, "out of memory (ctrl buffer alloc)\n"); + goto alloc_fail2; + } + xr_usb_serial->ctrl_buffer = buf; + + if (xr_usb_serial_write_buffers_alloc(xr_usb_serial) < 0) { + dev_err(&intf->dev, "out of memory (write buffer alloc)\n"); + goto alloc_fail4; + } + + xr_usb_serial->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); + if (!xr_usb_serial->ctrlurb) { + dev_err(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); + goto alloc_fail5; + } + for (i = 0; i < num_rx_buf; i++) { + struct xr_usb_serial_rb *rb = &(xr_usb_serial->read_buffers[i]); + struct urb *urb; + + rb->base = usb_alloc_coherent(xr_usb_serial->dev, readsize, GFP_KERNEL, + &rb->dma); + if (!rb->base) { + dev_err(&intf->dev, "out of memory " + "(read bufs usb_alloc_coherent)\n"); + goto alloc_fail6; + } + rb->index = i; + rb->instance = xr_usb_serial; + + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) { + dev_err(&intf->dev, + "out of memory (read urbs usb_alloc_urb)\n"); + goto alloc_fail6; + } + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + urb->transfer_dma = rb->dma; + if (xr_usb_serial->is_int_ep) { + usb_fill_int_urb(urb, xr_usb_serial->dev, + xr_usb_serial->rx_endpoint, + rb->base, + xr_usb_serial->readsize, + xr_usb_serial_read_bulk_callback, rb, + xr_usb_serial->bInterval); + } else { + usb_fill_bulk_urb(urb, xr_usb_serial->dev, + xr_usb_serial->rx_endpoint, + rb->base, + xr_usb_serial->readsize, + xr_usb_serial_read_bulk_callback, rb); + } + + xr_usb_serial->read_urbs[i] = urb; + __set_bit(i, &xr_usb_serial->read_urbs_free); + } + for (i = 0; i < XR_USB_SERIAL_NW; i++) { + struct xr_usb_serial_wb *snd = &(xr_usb_serial->wb[i]); + + snd->urb = usb_alloc_urb(0, GFP_KERNEL); + if (snd->urb == NULL) { + dev_err(&intf->dev, + "out of memory (write urbs usb_alloc_urb)\n"); + goto alloc_fail7; + } + + if (usb_endpoint_xfer_int(epwrite)) + usb_fill_int_urb(snd->urb, usb_dev, +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0) + usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), +#else + usb_sndintpipe(usb_dev, epwrite->bEndpointAddress), +#endif + NULL, xr_usb_serial->writesize, xr_usb_serial_write_bulk, snd, epwrite->bInterval); + else + usb_fill_bulk_urb(snd->urb, usb_dev, + usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), + NULL, xr_usb_serial->writesize, xr_usb_serial_write_bulk, snd); + snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + snd->instance = xr_usb_serial; + } + + usb_set_intfdata(intf, xr_usb_serial); + + i = device_create_file(&intf->dev, &dev_attr_bmCapabilities); + if (i < 0) + goto alloc_fail7; + + if (cfd) { /* export the country data */ + xr_usb_serial->country_codes = kmalloc(cfd->bLength - 4, GFP_KERNEL); + if (!xr_usb_serial->country_codes) + goto skip_countries; + xr_usb_serial->country_code_size = cfd->bLength - 4; + memcpy(xr_usb_serial->country_codes, (u8 *)&cfd->wCountyCode0, + cfd->bLength - 4); + xr_usb_serial->country_rel_date = cfd->iCountryCodeRelDate; + + i = device_create_file(&intf->dev, &dev_attr_wCountryCodes); + if (i < 0) { + kfree(xr_usb_serial->country_codes); + xr_usb_serial->country_codes = NULL; + xr_usb_serial->country_code_size = 0; + goto skip_countries; + } + + i = device_create_file(&intf->dev, + &dev_attr_iCountryCodeRelDate); + if (i < 0) { + device_remove_file(&intf->dev, &dev_attr_wCountryCodes); + kfree(xr_usb_serial->country_codes); + xr_usb_serial->country_codes = NULL; + xr_usb_serial->country_code_size = 0; + goto skip_countries; + } + } + +skip_countries: + usb_fill_int_urb(xr_usb_serial->ctrlurb, usb_dev, + usb_rcvintpipe(usb_dev, epctrl->bEndpointAddress), + xr_usb_serial->ctrl_buffer, ctrlsize, xr_usb_serial_ctrl_irq, xr_usb_serial, + /* works around buggy devices */ + epctrl->bInterval ? epctrl->bInterval : 0xff); + xr_usb_serial->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + xr_usb_serial->ctrlurb->transfer_dma = xr_usb_serial->ctrl_dma; + + dev_info(&intf->dev, "ttyXR_USB_SERIAL%d: USB XR_USB_SERIAL device\n", minor); + + xr_usb_serial_pre_setup(xr_usb_serial); + + xr_usb_serial_set_control(xr_usb_serial, xr_usb_serial->ctrlout); + + xr_usb_serial->line.dwDTERate = cpu_to_le32(9600); + xr_usb_serial->line.bDataBits = 8; + xr_usb_serial_set_line(xr_usb_serial, &xr_usb_serial->line); + + usb_driver_claim_interface(&xr_usb_serial_driver, data_interface, xr_usb_serial); + usb_set_intfdata(data_interface, xr_usb_serial); + + usb_get_intf(control_interface); +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0) + tty_register_device(xr_usb_serial_tty_driver, minor, &control_interface->dev); +#else + tty_dev = tty_port_register_device(&xr_usb_serial->port, xr_usb_serial_tty_driver, minor, + &control_interface->dev); + if (IS_ERR(tty_dev)) { + rv = PTR_ERR(tty_dev); + goto alloc_fail8; + } +#endif + +#ifdef CONFIG_GPIOLIB + /* Setup GPIO cotroller */ + gpiochip_base = 0; + + xr_usb_serial->xr_gpio.owner = THIS_MODULE; + xr_usb_serial->xr_gpio.label = dev_name(&control_interface->dev); + xr_usb_serial->xr_gpio.direction_input = xr_usb_gpio_dir_input; + xr_usb_serial->xr_gpio.get = xr_usb_gpio_get; + xr_usb_serial->xr_gpio.direction_output = xr_usb_gpio_dir_output; + xr_usb_serial->xr_gpio.set = xr_usb_gpio_set; + xr_usb_serial->xr_gpio.base = gpiochip_base; + xr_usb_serial->xr_gpio.ngpio = 10; + xr_usb_serial->xr_gpio.can_sleep = 1; + + rv = gpiochip_add(&xr_usb_serial->xr_gpio); + + if (rv != 0) { + // gpiochip numbers not available, start from 0 + xr_usb_serial->xr_gpio.base = 0; + } + + while (rv != 0) { + xr_usb_serial->xr_gpio.base += 10; + + if (xr_usb_serial->xr_gpio.base > 502) { + // max gpio number = 512 + // we ran out of gpios?? + break; + } + rv = gpiochip_add(&xr_usb_serial->xr_gpio); + } + xr_usb_serial->rv_gpio_created = rv; + if (rv == 0) { + dev_dbg(&xr_usb_serial->control->dev, "gpiochip%d added", + xr_usb_serial->xr_gpio.base); + } else { + dev_dbg(&xr_usb_serial->control->dev, "failed to add gpiochip\n"); + } + +#endif + + return 0; +alloc_fail8: + if (xr_usb_serial->country_codes) { + device_remove_file(&xr_usb_serial->control->dev, + &dev_attr_wCountryCodes); + device_remove_file(&xr_usb_serial->control->dev, + &dev_attr_iCountryCodeRelDate); + } + device_remove_file(&xr_usb_serial->control->dev, &dev_attr_bmCapabilities); +alloc_fail7: + usb_set_intfdata(intf, NULL); + for (i = 0; i < XR_USB_SERIAL_NW; i++) + usb_free_urb(xr_usb_serial->wb[i].urb); +alloc_fail6: + for (i = 0; i < num_rx_buf; i++) + usb_free_urb(xr_usb_serial->read_urbs[i]); + xr_usb_serial_read_buffers_free(xr_usb_serial); + usb_free_urb(xr_usb_serial->ctrlurb); +alloc_fail5: + xr_usb_serial_write_buffers_free(xr_usb_serial); +alloc_fail4: + usb_free_coherent(usb_dev, ctrlsize, xr_usb_serial->ctrl_buffer, xr_usb_serial->ctrl_dma); +alloc_fail2: + xr_usb_serial_release_minor(xr_usb_serial); + kfree(xr_usb_serial); +alloc_fail: + return rv; +} + +static void stop_data_traffic(struct xr_usb_serial *xr_usb_serial) +{ + int i; + + dev_dbg(&xr_usb_serial->control->dev, "%s\n", __func__); + + usb_kill_urb(xr_usb_serial->ctrlurb); + for (i = 0; i < XR_USB_SERIAL_NW; i++) + usb_kill_urb(xr_usb_serial->wb[i].urb); + for (i = 0; i < xr_usb_serial->rx_buflimit; i++) + usb_kill_urb(xr_usb_serial->read_urbs[i]); + + cancel_work_sync(&xr_usb_serial->work); +} + +static void xr_usb_serial_disconnect(struct usb_interface *intf) +{ + struct xr_usb_serial *xr_usb_serial = usb_get_intfdata(intf); + struct usb_device *usb_dev = interface_to_usbdev(intf); + struct tty_struct *tty; + int i; + + dev_dbg(&intf->dev, "%s\n", __func__); + + /* sibling interface is already cleaning up */ + if (!xr_usb_serial) + return; + + mutex_lock(&xr_usb_serial->mutex); + xr_usb_serial->disconnected = true; + if (xr_usb_serial->country_codes) { + device_remove_file(&xr_usb_serial->control->dev, + &dev_attr_wCountryCodes); + device_remove_file(&xr_usb_serial->control->dev, + &dev_attr_iCountryCodeRelDate); + } + device_remove_file(&xr_usb_serial->control->dev, &dev_attr_bmCapabilities); + usb_set_intfdata(xr_usb_serial->control, NULL); + usb_set_intfdata(xr_usb_serial->data, NULL); + mutex_unlock(&xr_usb_serial->mutex); + + tty = tty_port_tty_get(&xr_usb_serial->port); + if (tty) { + tty_vhangup(tty); + tty_kref_put(tty); + } + stop_data_traffic(xr_usb_serial); +#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 7, 0) + tty_unregister_device(xr_usb_serial_tty_driver, xr_usb_serial->minor); +#endif + + usb_free_urb(xr_usb_serial->ctrlurb); + for (i = 0; i < XR_USB_SERIAL_NW; i++) + usb_free_urb(xr_usb_serial->wb[i].urb); + for (i = 0; i < xr_usb_serial->rx_buflimit; i++) + usb_free_urb(xr_usb_serial->read_urbs[i]); + xr_usb_serial_write_buffers_free(xr_usb_serial); + usb_free_coherent(usb_dev, xr_usb_serial->ctrlsize, xr_usb_serial->ctrl_buffer, xr_usb_serial->ctrl_dma); + xr_usb_serial_read_buffers_free(xr_usb_serial); + + if (!xr_usb_serial->combined_interfaces) + usb_driver_release_interface(&xr_usb_serial_driver, intf == xr_usb_serial->control ? + xr_usb_serial->data : xr_usb_serial->control); + + tty_port_put(&xr_usb_serial->port); +} + +#ifdef CONFIG_PM +static int xr_usb_serial_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct xr_usb_serial *xr_usb_serial = usb_get_intfdata(intf); + int cnt; + + if (PMSG_IS_AUTO(message)) { + int b; + + spin_lock_irq(&xr_usb_serial->write_lock); + b = xr_usb_serial->transmitting; + spin_unlock_irq(&xr_usb_serial->write_lock); + if (b) + return -EBUSY; + } + + spin_lock_irq(&xr_usb_serial->read_lock); + spin_lock(&xr_usb_serial->write_lock); + cnt = xr_usb_serial->susp_count++; + spin_unlock(&xr_usb_serial->write_lock); + spin_unlock_irq(&xr_usb_serial->read_lock); + + if (cnt) + return 0; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 2) + if (test_bit(ASYNCB_INITIALIZED, &xr_usb_serial->port.flags)) +#endif + stop_data_traffic(xr_usb_serial); + + return 0; +} + +static int xr_usb_serial_resume(struct usb_interface *intf) +{ + struct xr_usb_serial *xr_usb_serial = usb_get_intfdata(intf); + struct xr_usb_serial_wb *wb; + int rv = 0; + int cnt; + + spin_lock_irq(&xr_usb_serial->read_lock); + xr_usb_serial->susp_count -= 1; + cnt = xr_usb_serial->susp_count; + spin_unlock_irq(&xr_usb_serial->read_lock); + + if (cnt) + return 0; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0) + if (test_bit(ASYNCB_INITIALIZED, &xr_usb_serial->port.flags)) { +#else + if (tty_port_initialized(&xr_usb_serial->port)) { +#endif + rv = usb_submit_urb(xr_usb_serial->ctrlurb, GFP_NOIO); + + spin_lock_irq(&xr_usb_serial->write_lock); + if (xr_usb_serial->delayed_wb) { + wb = xr_usb_serial->delayed_wb; + xr_usb_serial->delayed_wb = NULL; + spin_unlock_irq(&xr_usb_serial->write_lock); + xr_usb_serial_start_wb(xr_usb_serial, wb); + } else { + spin_unlock_irq(&xr_usb_serial->write_lock); + } + + /* + * delayed error checking because we must + * do the write path at all cost + */ + if (rv < 0) + goto err_out; + + rv = xr_usb_serial_submit_read_urbs(xr_usb_serial, GFP_NOIO); + } + +err_out: + return rv; +} + +static int xr_usb_serial_reset_resume(struct usb_interface *intf) +{ + struct xr_usb_serial *xr_usb_serial = usb_get_intfdata(intf); +#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 9, 0) +#else + struct tty_struct *tty; +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0) + if (test_bit(ASYNCB_INITIALIZED, &xr_usb_serial->port.flags)){ +#else + if (tty_port_initialized(&xr_usb_serial->port)) { +#endif +#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 9, 0) + tty_port_tty_hangup(&xr_usb_serial->port, false); +#else + tty = tty_port_tty_get(&xr_usb_serial->port); + if (tty) { + tty_hangup(tty); + tty_kref_put(tty); + } +#endif + } + return xr_usb_serial_resume(intf); +} + +#endif /* CONFIG_PM */ + +/* + * USB driver structure. + */ +static const struct usb_device_id xr_usb_serial_ids[] = { + { USB_DEVICE(0x04e2, 0x1410)}, + { USB_DEVICE(0x04e2, 0x1411)}, + { USB_DEVICE(0x04e2, 0x1412)}, + { USB_DEVICE(0x04e2, 0x1414)}, + { USB_DEVICE(0x04e2, 0x1420)}, + { USB_DEVICE(0x04e2, 0x1421)}, + { USB_DEVICE(0x04e2, 0x1422)}, + { USB_DEVICE(0x04e2, 0x1424)}, + { USB_DEVICE(0x04e2, 0x1400)}, + { USB_DEVICE(0x04e2, 0x1401)}, + { USB_DEVICE(0x04e2, 0x1402)}, + { USB_DEVICE(0x04e2, 0x1403)}, + { } +}; + +MODULE_DEVICE_TABLE(usb, xr_usb_serial_ids); + +static struct usb_driver xr_usb_serial_driver = { + .name = "cdc_xr_usb_serial", + .probe = xr_usb_serial_probe, + .disconnect = xr_usb_serial_disconnect, +#ifdef CONFIG_PM + .suspend = xr_usb_serial_suspend, + .resume = xr_usb_serial_resume, + .reset_resume = xr_usb_serial_reset_resume, +#endif + .id_table = xr_usb_serial_ids, +#ifdef CONFIG_PM + .supports_autosuspend = 1, +#endif + .disable_hub_initiated_lpm = 1, +}; + +/* + * TTY driver structures. + */ + +static const struct tty_operations xr_usb_serial_ops = { + .install = xr_usb_serial_tty_install, + .open = xr_usb_serial_tty_open, + .close = xr_usb_serial_tty_close, + .cleanup = xr_usb_serial_tty_cleanup, + .hangup = xr_usb_serial_tty_hangup, + .write = xr_usb_serial_tty_write, + .write_room = xr_usb_serial_tty_write_room, +#ifdef CONFIG_COMPAT + .compat_ioctl = xr_usb_serial_tty_compat_ioctl, +#endif + .ioctl = xr_usb_serial_tty_ioctl, + .throttle = xr_usb_serial_tty_throttle, + .unthrottle = xr_usb_serial_tty_unthrottle, + .chars_in_buffer = xr_usb_serial_tty_chars_in_buffer, + .break_ctl = xr_usb_serial_tty_break_ctl, + .set_termios = xr_usb_serial_tty_set_termios, + .tiocmget = xr_usb_serial_tty_tiocmget, + .tiocmset = xr_usb_serial_tty_tiocmset, +}; + +/* + * Init / exit. + */ + +static int __init xr_usb_serial_init(void) +{ + int retval; + xr_usb_serial_tty_driver = alloc_tty_driver(XR_USB_SERIAL_TTY_MINORS); + if (!xr_usb_serial_tty_driver) + return -ENOMEM; + xr_usb_serial_tty_driver->driver_name = "xr_usb_serial", + xr_usb_serial_tty_driver->name = "ttyXRUSB", + xr_usb_serial_tty_driver->major = XR_USB_SERIAL_TTY_MAJOR, + xr_usb_serial_tty_driver->minor_start = 0, + xr_usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL, + xr_usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL, + xr_usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + xr_usb_serial_tty_driver->init_termios = tty_std_termios; + xr_usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | + HUPCL | CLOCAL; + tty_set_operations(xr_usb_serial_tty_driver, &xr_usb_serial_ops); + + retval = tty_register_driver(xr_usb_serial_tty_driver); + if (retval) { + put_tty_driver(xr_usb_serial_tty_driver); + return retval; + } + + retval = usb_register(&xr_usb_serial_driver); + if (retval) { + tty_unregister_driver(xr_usb_serial_tty_driver); + put_tty_driver(xr_usb_serial_tty_driver); + return retval; + } + + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); + + return 0; +} + +static void __exit xr_usb_serial_exit(void) +{ + usb_deregister(&xr_usb_serial_driver); + tty_unregister_driver(xr_usb_serial_tty_driver); + put_tty_driver(xr_usb_serial_tty_driver); +} + +module_init(xr_usb_serial_init); +module_exit(xr_usb_serial_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV_MAJOR(XR_USB_SERIAL_TTY_MAJOR); diff --git a/package/kernel/xr-usb-serial/src/xr_usb_serial_common.h b/package/kernel/xr-usb-serial/src/xr_usb_serial_common.h new file mode 100644 index 000000000..efcbba8ce --- /dev/null +++ b/package/kernel/xr-usb-serial/src/xr_usb_serial_common.h @@ -0,0 +1,197 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * CMSPAR, some architectures can't have space and mark parity. + */ + +#ifndef CMSPAR +#define CMSPAR 0 +#endif + +/* + * Major and minor numbers. + */ + +#define XR_USB_SERIAL_TTY_MAJOR 266 +#define XR_USB_SERIAL_TTY_MINORS 32 + +/* + * Requests. + */ + +#define USB_RT_XR_USB_SERIAL (USB_TYPE_CLASS | USB_RECIP_INTERFACE) + +/* + * Output control lines. + */ + +#define XR_USB_SERIAL_CTRL_DTR 0x01 +#define XR_USB_SERIAL_CTRL_RTS 0x02 + +/* + * Input control lines and line errors. + */ + +#define XR_USB_SERIAL_CTRL_DCD 0x01 +#define XR_USB_SERIAL_CTRL_DSR 0x02 +#define XR_USB_SERIAL_CTRL_BRK 0x04 +#define XR_USB_SERIAL_CTRL_RI 0x08 + +#define XR_USB_SERIAL_CTRL_FRAMING 0x10 +#define XR_USB_SERIAL_CTRL_PARITY 0x20 +#define XR_USB_SERIAL_CTRL_OVERRUN 0x40 + +/* + * Internal driver structures. + */ + +/* + * The only reason to have several buffers is to accommodate assumptions + * in line disciplines. They ask for empty space amount, receive our URB size, + * and proceed to issue several 1-character writes, assuming they will fit. + * The very first write takes a complete URB. Fortunately, this only happens + * when processing onlcr, so we only need 2 buffers. These values must be + * powers of 2. + */ +#define XR_USB_SERIAL_NW 16 +#define XR_USB_SERIAL_NR 16 + +#define RAMCTL_BUFFER_PARITY 0x1 +#define RAMCTL_BUFFER_BREAK 0x2 +#define RAMCTL_BUFFER_FRAME 0x4 +#define RAMCTL_BUFFER_OVERRUN 0x8 + +struct xr_usb_serial_wb { + unsigned char *buf; + dma_addr_t dmah; + int len; + int use; + struct urb *urb; + struct xr_usb_serial *instance; +}; + +struct xr_usb_serial_rb { + int size; + unsigned char *base; + dma_addr_t dma; + int index; + struct xr_usb_serial *instance; +}; + +struct reg_addr_map { + unsigned int uart_enable_addr; + unsigned int uart_format_addr; + unsigned int uart_flow_addr; + unsigned int uart_loopback_addr; + unsigned int uart_xon_char_addr; + unsigned int uart_xoff_char_addr; + unsigned int uart_gpio_mode_addr; + unsigned int uart_gpio_dir_addr; + unsigned int uart_gpio_set_addr; + unsigned int uart_gpio_clr_addr; + unsigned int uart_gpio_status_addr; + unsigned int tx_break_addr; + unsigned int uart_custom_driver; + unsigned int uart_low_latency; +}; + +struct xr_usb_serial { + struct usb_device *dev; /* the corresponding usb device */ + struct usb_interface *control; /* control interface */ + struct usb_interface *data; /* data interface */ + struct tty_port port; /* our tty port data */ + struct urb *ctrlurb; /* urbs */ + u8 *ctrl_buffer; /* buffers of urbs */ + dma_addr_t ctrl_dma; /* dma handles of buffers */ + u8 *country_codes; /* country codes from device */ + unsigned int country_code_size; /* size of this buffer */ + unsigned int country_rel_date; /* release date of version */ + struct xr_usb_serial_wb wb[XR_USB_SERIAL_NW]; + unsigned long read_urbs_free; + struct urb *read_urbs[XR_USB_SERIAL_NR]; + struct xr_usb_serial_rb read_buffers[XR_USB_SERIAL_NR]; + int rx_buflimit; + int rx_endpoint; + spinlock_t read_lock; + int write_used; /* number of non-empty write buffers */ + int transmitting; + spinlock_t write_lock; + struct mutex mutex; + bool disconnected; + struct usb_cdc_line_coding line; /* bits, stop, parity */ + struct work_struct work; /* work queue entry for line discipline waking up */ + unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ + unsigned int ctrlout; /* output control lines (DTR, RTS) */ + unsigned int writesize; /* max packet size for the output bulk endpoint */ + unsigned int readsize,ctrlsize; /* buffer sizes for freeing */ + unsigned int minor; /* xr_usb_serial minor number */ + unsigned char clocal; /* termios CLOCAL */ + unsigned int ctrl_caps; /* control capabilities from the class specific header */ + unsigned int susp_count; /* number of suspended interfaces */ + unsigned int combined_interfaces:1; /* control and data collapsed */ + unsigned int is_int_ep:1; /* interrupt endpoints contrary to spec used */ + unsigned int throttled:1; /* actually throttled */ + unsigned int throttle_req:1; /* throttle requested */ + u8 bInterval; + struct xr_usb_serial_wb *delayed_wb; /* write queued for a device about to be woken */ + unsigned int channel; + int preciseflags; /* USB: wide mode, TTY: flags per character */ + int trans9; /* USB: wide mode, serial 9N1 */ + int have_extra_byte; + int extra_byte; + + unsigned short DeviceVendor; + unsigned short DeviceProduct; + struct reg_addr_map reg_map; +#ifdef CONFIG_GPIOLIB + struct gpio_chip xr_gpio; + int rv_gpio_created; +#endif +}; + +#define CDC_DATA_INTERFACE_TYPE 0x0a + +/* constants describing various quirks and errors */ +#define NO_UNION_NORMAL 1 +#define SINGLE_RX_URB 2 +#define NO_CAP_LINE 4 +#define NOT_A_MODEM 8 +#define NO_DATA_INTERFACE 16 +#define IGNORE_DEVICE 32 + + +#define UART_ENABLE_TX 1 +#define UART_ENABLE_RX 2 + +#define UART_GPIO_CLR_DTR 0x8 +#define UART_GPIO_SET_DTR 0x8 +#define UART_GPIO_CLR_RTS 0x20 +#define UART_GPIO_SET_RTS 0x20 + +#define LOOPBACK_ENABLE_TX_RX 1 +#define LOOPBACK_ENABLE_RTS_CTS 2 +#define LOOPBACK_ENABLE_DTR_DSR 4 + +#define UART_FLOW_MODE_NONE 0x0 +#define UART_FLOW_MODE_HW 0x1 +#define UART_FLOW_MODE_SW 0x2 + +#define UART_GPIO_MODE_SEL_GPIO 0x0 +#define UART_GPIO_MODE_SEL_RTS_CTS 0x1 + +#define XR2280x_FUNC_MGR_OFFSET 0x40 + diff --git a/package/kernel/xr-usb-serial/src/xr_usb_serial_hal.c b/package/kernel/xr-usb-serial/src/xr_usb_serial_hal.c new file mode 100644 index 000000000..26f5b8a36 --- /dev/null +++ b/package/kernel/xr-usb-serial/src/xr_usb_serial_hal.c @@ -0,0 +1,821 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define XR_SET_MAP_XR2280X 5 +#define XR_GET_MAP_XR2280X 5 + +#define XR_SET_MAP_XR21B142X 0 +#define XR_GET_MAP_XR21B142X 0 + +#define XR_SET_MAP_XR21V141X 0 +#define XR_GET_MAP_XR21V141X 1 + +#define XR_SET_MAP_XR21B1411 0 +#define XR_GET_MAP_XR21B1411 1 + + +int xr_usb_serial_set_reg(struct xr_usb_serial *xr_usb_serial,int regnum, int value) +{ + int result; + int channel = 0; + //dev_info(&xr_usb_serial->control->dev, "%s Channel:%d 0x%02x = 0x%02x\n", __func__,channel,regnum, value); + if((xr_usb_serial->DeviceProduct&0xfff0) == 0x1400) + { + int XR2280xaddr = XR2280x_FUNC_MGR_OFFSET + regnum; + result = usb_control_msg(xr_usb_serial->dev, /* usb device */ + usb_sndctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */ + XR_SET_MAP_XR2280X, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR, /* request_type */ + value, /* request value */ + XR2280xaddr, /* index */ + NULL, /* data */ + 0, /* size */ + 5000); /* timeout */ + } + else if((xr_usb_serial->DeviceProduct == 0x1410) || + (xr_usb_serial->DeviceProduct == 0x1412) || + (xr_usb_serial->DeviceProduct == 0x1414)) + { + if(xr_usb_serial->channel) + channel = xr_usb_serial->channel - 1; + result = usb_control_msg(xr_usb_serial->dev, /* usb device */ + usb_sndctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */ + XR_SET_MAP_XR21V141X, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR, /* request_type */ + value, /* request value */ + regnum | (channel << 8), /* index */ + NULL, /* data */ + 0, /* size */ + 5000); /* timeout */ + } + else if(xr_usb_serial->DeviceProduct == 0x1411) + { + result = usb_control_msg(xr_usb_serial->dev, /* usb device */ + usb_sndctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */ + XR_SET_MAP_XR21B1411, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR, /* request_type */ + value, /* request value */ + regnum , /* index */ + NULL, /* data */ + 0, /* size */ + 5000); /* timeout */ + } + else if((xr_usb_serial->DeviceProduct == 0x1420)|| + (xr_usb_serial->DeviceProduct == 0x1422)|| + (xr_usb_serial->DeviceProduct == 0x1424)) + { + channel = (xr_usb_serial->channel - 4)*2; + result = usb_control_msg(xr_usb_serial->dev, /* usb device */ + usb_sndctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */ + XR_SET_MAP_XR21B142X, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR | 1, /* request_type */ + value, /* request value */ + regnum | (channel << 8), /* index */ + NULL, /* data */ + 0, /* size */ + 5000); /* timeout */ + } + else + { + result = -1; + } + if(result < 0) + dev_err(&xr_usb_serial->control->dev, "%s Error:%d\n", __func__,result); + return result; +} + +int xr_usb_serial_set_reg_ext(struct xr_usb_serial *xr_usb_serial,int channel,int regnum, int value) +{ + int result; + int XR2280xaddr = XR2280x_FUNC_MGR_OFFSET + regnum; + //dev_info(&xr_usb_serial->control->dev, "%s channel:%d 0x%02x = 0x%02x\n", __func__,channel,regnum, value); + if((xr_usb_serial->DeviceProduct&0xfff0) == 0x1400) + { + result = usb_control_msg(xr_usb_serial->dev, /* usb device */ + usb_sndctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */ + XR_SET_MAP_XR2280X, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR, /* request_type */ + value, /* request value */ + XR2280xaddr, /* index */ + NULL, /* data */ + 0, /* size */ + 5000); /* timeout */ + } + else if((xr_usb_serial->DeviceProduct == 0x1410) || + (xr_usb_serial->DeviceProduct == 0x1412) || + (xr_usb_serial->DeviceProduct == 0x1414)) + { + result = usb_control_msg(xr_usb_serial->dev, /* usb device */ + usb_sndctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */ + XR_SET_MAP_XR21V141X, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR, /* request_type */ + value, /* request value */ + regnum | (channel << 8), /* index */ + NULL, /* data */ + 0, /* size */ + 5000); /* timeout */ + } + else if(xr_usb_serial->DeviceProduct == 0x1411) + { + result = usb_control_msg(xr_usb_serial->dev, /* usb device */ + usb_sndctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */ + XR_SET_MAP_XR21B1411, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR , /* request_type */ + value, /* request value */ + regnum , /* index */ + NULL, /* data */ + 0, /* size */ + 5000); /* timeout */ + } + else if((xr_usb_serial->DeviceProduct == 0x1420)|| + (xr_usb_serial->DeviceProduct == 0x1422)|| + (xr_usb_serial->DeviceProduct == 0x1424)) + { + result = usb_control_msg(xr_usb_serial->dev, /* usb device */ + usb_sndctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */ + XR_SET_MAP_XR21B142X, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR | 1, /* request_type */ + value, /* request value */ + regnum | (channel << 8), /* index */ + NULL, /* data */ + 0, /* size */ + 5000); /* timeout */ + } + else + { + result = -1; + } + if(result < 0) + dev_err(&xr_usb_serial->control->dev, "%s Error:%d\n", __func__,result); + return result; +} + +int xr_usb_serial_get_reg(struct xr_usb_serial *xr_usb_serial,int regnum, short *value) +{ + int result; + int channel = 0; + short *dmadata; + + /* Use dynamic memory instead of statically allocated buffer + This is to avoid Error -11 (EAGAIN) for Kernel no longer accept static allocated buffer after 4.9 */ + dmadata = kmalloc(2, GFP_KERNEL); + + if (!dmadata) + { + dev_err(&xr_usb_serial->control->dev, "[func:%s,line:%d] error no memory allocated!! \n", __func__,__LINE__); + return -ENOMEM; + } + + if((xr_usb_serial->DeviceProduct&0xfff0) == 0x1400) + { + int XR2280xaddr = XR2280x_FUNC_MGR_OFFSET + regnum; + result = usb_control_msg(xr_usb_serial->dev, /* usb device */ + usb_rcvctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */ + XR_GET_MAP_XR2280X, /* request */ + USB_DIR_IN | USB_TYPE_VENDOR , /* request_type */ + 0, /* request value */ + XR2280xaddr, /* index */ + dmadata, /* data */ + 2, /* size */ + 5000); /* timeout */ + memcpy(value, dmadata, 2); + } + else if((xr_usb_serial->DeviceProduct == 0x1410) || + (xr_usb_serial->DeviceProduct == 0x1412) || + (xr_usb_serial->DeviceProduct == 0x1414)) + { + if(xr_usb_serial->channel) + channel = xr_usb_serial->channel -1; + result = usb_control_msg(xr_usb_serial->dev, /* usb device */ + usb_rcvctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */ + XR_GET_MAP_XR21V141X, /* request */ + USB_DIR_IN | USB_TYPE_VENDOR, /* request_type */ + 0, /* request value */ + regnum | (channel << 8), /* index */ + dmadata, /* data */ + 1, /* size */ + 5000); /* timeout */ + memcpy(value, dmadata, 1); + } + else if(xr_usb_serial->DeviceProduct == 0x1411) + { + result = usb_control_msg(xr_usb_serial->dev, /* usb device */ + usb_rcvctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */ + XR_GET_MAP_XR21B1411, /* request */ + USB_DIR_IN | USB_TYPE_VENDOR, /* request_type */ + 0, /* request value */ + regnum, /* index */ + dmadata, /* data */ + 2, /* size */ + 5000); /* timeout */ + memcpy(value, dmadata, 2); + } + else if((xr_usb_serial->DeviceProduct == 0x1420)|| + (xr_usb_serial->DeviceProduct == 0x1422)|| + (xr_usb_serial->DeviceProduct == 0x1424)) + { + channel = (xr_usb_serial->channel -4)*2; + result = usb_control_msg(xr_usb_serial->dev, /* usb device */ + usb_rcvctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */ + XR_GET_MAP_XR21B142X, /* request */ + USB_DIR_IN | USB_TYPE_VENDOR | 1, /* request_type */ + 0, /* request value */ + regnum | (channel << 8), /* index */ + dmadata, /* data */ + 2, /* size */ + 5000); /* timeout */ + memcpy(value, dmadata, 2); + } + else + { + result = -1; + } + + if(result < 0) + dev_err(&xr_usb_serial->control->dev, "%s channel:%d Reg 0x%x Error:%d\n", __func__,channel,regnum,result); + //else + //dev_info(&xr_usb_serial->control->dev, "%s channel:%d 0x%x = 0x%04x\n", __func__,channel,regnum, *value); + + kfree(dmadata); + return result; +} + +int xr_usb_serial_get_reg_ext(struct xr_usb_serial *xr_usb_serial,int channel,int regnum, short *value) +{ + int result; + int XR2280xaddr = XR2280x_FUNC_MGR_OFFSET + regnum; + short *dmadata; + + /* Use dynamic memory instead of statically allocated buffer + This is to avoid Error -11 (EAGAIN) for Kernel no longer accept static allocated buffer after 4.9 */ + dmadata = kmalloc(2, GFP_KERNEL); + + if (!dmadata) + { + dev_err(&xr_usb_serial->control->dev, "[func:%s,line:%d] error no memory allocated!! \n", __func__,__LINE__); + return -ENOMEM; + } + + if((xr_usb_serial->DeviceProduct&0xfff0) == 0x1400) + { + result = usb_control_msg(xr_usb_serial->dev, /* usb device */ + usb_rcvctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */ + XR_GET_MAP_XR2280X, /* request */ + USB_DIR_IN | USB_TYPE_VENDOR , /* request_type */ + 0, /* request value */ + XR2280xaddr, /* index */ + dmadata, /* data */ + 2, /* size */ + 5000); /* timeout */ + memcpy(value, dmadata, 2); + } + else if((xr_usb_serial->DeviceProduct == 0x1410) || + (xr_usb_serial->DeviceProduct == 0x1412) || + (xr_usb_serial->DeviceProduct == 0x1414)) + { + result = usb_control_msg(xr_usb_serial->dev, /* usb device */ + usb_rcvctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */ + XR_GET_MAP_XR21V141X, /* request */ + USB_DIR_IN | USB_TYPE_VENDOR, /* request_type */ + 0, /* request value */ + regnum | (channel << 8), /* index */ + dmadata, /* data */ + 1, /* size */ + 5000); /* timeout */ + memcpy(value, dmadata, 1); + } + else if(xr_usb_serial->DeviceProduct == 0x1411) + { + result = usb_control_msg(xr_usb_serial->dev, /* usb device */ + usb_rcvctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */ + XR_GET_MAP_XR21B1411, /* request */ + USB_DIR_IN | USB_TYPE_VENDOR , /* request_type */ + 0, /* request value */ + regnum | (channel << 8), /* index */ + dmadata, /* data */ + 2, /* size */ + 5000); /* timeout */ + memcpy(value, dmadata, 2); + } + else if((xr_usb_serial->DeviceProduct == 0x1420)|| + (xr_usb_serial->DeviceProduct == 0x1422)|| + (xr_usb_serial->DeviceProduct == 0x1424)) + { + result = usb_control_msg(xr_usb_serial->dev, /* usb device */ + usb_rcvctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */ + XR_GET_MAP_XR21B142X, /* request */ + USB_DIR_IN | USB_TYPE_VENDOR | 1, /* request_type */ + 0, /* request value */ + regnum | (channel << 8), /* index */ + dmadata, /* data */ + 2, /* size */ + 5000); /* timeout */ + memcpy(value, dmadata, 2); + } + else + { + result = -1; + } + + if(result < 0) + dev_err(&xr_usb_serial->control->dev, "%s Error:%d\n", __func__,result); + //else + //dev_info(&xr_usb_serial->control->dev, "%s channel:%d 0x%x = 0x%04x\n", __func__,channel,regnum, *value); + + kfree(dmadata); + return result; +} + +struct xr21v141x_baud_rate +{ + unsigned int tx; + unsigned int rx0; + unsigned int rx1; +}; + +static struct xr21v141x_baud_rate xr21v141x_baud_rates[] = { + { 0x000, 0x000, 0x000 }, + { 0x000, 0x000, 0x000 }, + { 0x100, 0x000, 0x100 }, + { 0x020, 0x400, 0x020 }, + { 0x010, 0x100, 0x010 }, + { 0x208, 0x040, 0x208 }, + { 0x104, 0x820, 0x108 }, + { 0x844, 0x210, 0x884 }, + { 0x444, 0x110, 0x444 }, + { 0x122, 0x888, 0x224 }, + { 0x912, 0x448, 0x924 }, + { 0x492, 0x248, 0x492 }, + { 0x252, 0x928, 0x292 }, + { 0X94A, 0X4A4, 0XA52 }, + { 0X52A, 0XAA4, 0X54A }, + { 0XAAA, 0x954, 0X4AA }, + { 0XAAA, 0x554, 0XAAA }, + { 0x555, 0XAD4, 0X5AA }, + { 0XB55, 0XAB4, 0X55A }, + { 0X6B5, 0X5AC, 0XB56 }, + { 0X5B5, 0XD6C, 0X6D6 }, + { 0XB6D, 0XB6A, 0XDB6 }, + { 0X76D, 0X6DA, 0XBB6 }, + { 0XEDD, 0XDDA, 0X76E }, + { 0XDDD, 0XBBA, 0XEEE }, + { 0X7BB, 0XF7A, 0XDDE }, + { 0XF7B, 0XEF6, 0X7DE }, + { 0XDF7, 0XBF6, 0XF7E }, + { 0X7F7, 0XFEE, 0XEFE }, + { 0XFDF, 0XFBE, 0X7FE }, + { 0XF7F, 0XEFE, 0XFFE }, + { 0XFFF, 0XFFE, 0XFFD }, +}; +#define UART_CLOCK_DIVISOR_0 0x004 +#define UART_CLOCK_DIVISOR_1 0x005 +#define UART_CLOCK_DIVISOR_2 0x006 +#define UART_TX_CLOCK_MASK_0 0x007 +#define UART_TX_CLOCK_MASK_1 0x008 +#define UART_RX_CLOCK_MASK_0 0x009 +#define UART_RX_CLOCK_MASK_1 0x00a + +static int xr21v141x_set_baud_rate(struct xr_usb_serial *xr_usb_serial, unsigned int rate) +{ + unsigned int divisor = 48000000 / rate; + unsigned int i = ((32 * 48000000) / rate) & 0x1f; + unsigned int tx_mask = xr21v141x_baud_rates[i].tx; + unsigned int rx_mask = (divisor & 1) ? xr21v141x_baud_rates[i].rx1 : xr21v141x_baud_rates[i].rx0; + + //dev_info(&xr_usb_serial->control->dev, "Setting baud rate to %d: i=%u div=%u tx=%03x rx=%03x\n", rate, i, divisor, tx_mask, rx_mask); + + xr_usb_serial_set_reg(xr_usb_serial,UART_CLOCK_DIVISOR_0, (divisor >> 0) & 0xff); + xr_usb_serial_set_reg(xr_usb_serial,UART_CLOCK_DIVISOR_1, (divisor >> 8) & 0xff); + xr_usb_serial_set_reg(xr_usb_serial,UART_CLOCK_DIVISOR_2, (divisor >> 16) & 0xff); + xr_usb_serial_set_reg(xr_usb_serial,UART_TX_CLOCK_MASK_0, (tx_mask >> 0) & 0xff); + xr_usb_serial_set_reg(xr_usb_serial,UART_TX_CLOCK_MASK_1, (tx_mask >> 8) & 0xff); + xr_usb_serial_set_reg(xr_usb_serial,UART_RX_CLOCK_MASK_0, (rx_mask >> 0) & 0xff); + xr_usb_serial_set_reg(xr_usb_serial,UART_RX_CLOCK_MASK_1, (rx_mask >> 8) & 0xff); + + return 0; +} +/* devices aren't required to support these requests. + * the cdc xr_usb_serial descriptor tells whether they do... + */ +int xr_usb_serial_set_control(struct xr_usb_serial *xr_usb_serial, unsigned int control) +{ + int ret = 0; + + if((xr_usb_serial->DeviceProduct == 0x1410) || + (xr_usb_serial->DeviceProduct == 0x1412) || + (xr_usb_serial->DeviceProduct == 0x1414)) + { + if (control & XR_USB_SERIAL_CTRL_DTR) + xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_gpio_clr_addr, 0x08); + else + xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_gpio_set_addr, 0x08); + + if (control & XR_USB_SERIAL_CTRL_RTS) + xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_gpio_clr_addr, 0x20); + else + xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_gpio_set_addr, 0x20); + } + else + { + ret = xr_usb_serial_ctrl_msg(xr_usb_serial, USB_CDC_REQ_SET_CONTROL_LINE_STATE, control, NULL, 0); + } + + return ret; +} + +int xr_usb_serial_set_line(struct xr_usb_serial *xr_usb_serial, struct usb_cdc_line_coding* line) +{ + int ret = 0; + unsigned int format_size; + unsigned int format_parity; + unsigned int format_stop; + if((xr_usb_serial->DeviceProduct == 0x1410) || + (xr_usb_serial->DeviceProduct == 0x1412) || + (xr_usb_serial->DeviceProduct == 0x1414)) + { + xr21v141x_set_baud_rate(xr_usb_serial,le32_to_cpu(line->dwDTERate)); + format_size = line->bDataBits; + format_parity = line->bParityType; + format_stop = line->bCharFormat; + xr_usb_serial_set_reg(xr_usb_serial, + xr_usb_serial->reg_map.uart_format_addr, + (format_size << 0) | (format_parity << 4) | (format_stop << 7) ); + } + else + { + ret = xr_usb_serial_ctrl_msg(xr_usb_serial, USB_CDC_REQ_SET_LINE_CODING, 0, line, sizeof *(line)); + } + return ret; +} + +int xr_usb_serial_set_flow_mode(struct xr_usb_serial *xr_usb_serial, struct tty_struct *tty, unsigned int cflag) +{ + unsigned int flow; + unsigned int gpio_mode; + + if (cflag & CRTSCTS) + { + //dev_dbg(&xr_usb_serial->control->dev, "xr_usb_serial_set_flow_mode:hardware\n"); + flow = UART_FLOW_MODE_HW; + gpio_mode = UART_GPIO_MODE_SEL_RTS_CTS; + } + else if (I_IXOFF(tty) || I_IXON(tty)) + { + unsigned char start_char = START_CHAR(tty); + unsigned char stop_char = STOP_CHAR(tty); + //dev_dbg(&xr_usb_serial->control->dev, "xr_usb_serial_set_flow_mode:software\n"); + flow = UART_FLOW_MODE_SW; + gpio_mode = UART_GPIO_MODE_SEL_GPIO; + + xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_xon_char_addr, start_char); + xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_xoff_char_addr, stop_char); + } + else + { + //dev_dbg(&xr_usb_serial->control->dev, "xr_usb_serial_set_flow_mode:none\n"); + flow = UART_FLOW_MODE_NONE; + gpio_mode = UART_GPIO_MODE_SEL_GPIO; + } + + if((xr_usb_serial->DeviceProduct == 0x1420)|| + (xr_usb_serial->DeviceProduct == 0x1422)|| + (xr_usb_serial->DeviceProduct == 0x1424)) + { + //Add support for the TXT and RXT function for 0x1420, 0x1422, 0x1424, by setting GPIO_MODE [9:8] = '11' + gpio_mode |= 0x300; + } + + xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_flow_addr, flow); + xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_mode_addr, gpio_mode); + return 0; +} + +int xr_usb_serial_send_break(struct xr_usb_serial *xr_usb_serial, int state) +{ + int ret = 0; + if((xr_usb_serial->DeviceProduct == 0x1410)|| + (xr_usb_serial->DeviceProduct == 0x1412)|| + (xr_usb_serial->DeviceProduct == 0x1414)) + { + if(state) + ret = xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.tx_break_addr,0xffff); + else + ret = xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.tx_break_addr,0); + } + else + { + ret = xr_usb_serial_ctrl_msg(xr_usb_serial, USB_CDC_REQ_SEND_BREAK, state, NULL, 0); + } + return ret; +} + +#define URM_REG_BLOCK 4 +#define URM_ENABLE_BASE 0x010 +#define URM_ENABLE_0_TX 0x001 +#define URM_ENABLE_0_RX 0x002 +#define URM_RESET_RX_FIFO_BASE 0x018 +#define URM_RESET_TX_FIFO_BASE 0x01C + +int xr_usb_serial_enable(struct xr_usb_serial *xr_usb_serial) +{ + int ret = 0; + int channel = xr_usb_serial->channel; + //dev_info(&xr_usb_serial->control->dev, "xr_usb_serial_enable channel=%d\n",channel); + if(channel) + channel--; + if((xr_usb_serial->DeviceProduct == 0x1410)|| + (xr_usb_serial->DeviceProduct == 0x1412)|| + (xr_usb_serial->DeviceProduct == 0x1414)) + { + ret = xr_usb_serial_set_reg_ext(xr_usb_serial,URM_REG_BLOCK,URM_ENABLE_BASE + channel,URM_ENABLE_0_TX); + ret = xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_enable_addr,UART_ENABLE_TX | UART_ENABLE_RX); + ret = xr_usb_serial_set_reg_ext(xr_usb_serial,URM_REG_BLOCK,URM_ENABLE_BASE + channel,URM_ENABLE_0_TX | URM_ENABLE_0_RX); + } + else + { + ret = xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_enable_addr,UART_ENABLE_TX | UART_ENABLE_RX); + } + + return ret; +} + +int xr_usb_serial_fifo_reset(struct xr_usb_serial *xr_usb_serial) +{ + int ret = 0; + int channel = xr_usb_serial->channel; + + if(channel) channel--; + if((xr_usb_serial->DeviceProduct == 0x1410)|| + (xr_usb_serial->DeviceProduct == 0x1412)|| + (xr_usb_serial->DeviceProduct == 0x1414)) + { + ret = xr_usb_serial_set_reg_ext(xr_usb_serial,URM_REG_BLOCK,URM_RESET_RX_FIFO_BASE + channel,0xff); + ret |= xr_usb_serial_set_reg_ext(xr_usb_serial,URM_REG_BLOCK,URM_RESET_TX_FIFO_BASE + channel,0xff); + } + return ret; +} + +int xr_usb_serial_disable(struct xr_usb_serial *xr_usb_serial) +{ + int ret = 0; + int channel = xr_usb_serial->channel; + //dev_info(&xr_usb_serial->control->dev, "xr_usb_serial_disable channel=%d\n",channel); + if(channel) channel--; + ret = xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_enable_addr,0); + if((xr_usb_serial->DeviceProduct == 0x1410)|| + (xr_usb_serial->DeviceProduct == 0x1412)|| + (xr_usb_serial->DeviceProduct == 0x1414)) + { + ret = xr_usb_serial_set_reg_ext(xr_usb_serial,URM_REG_BLOCK,URM_ENABLE_BASE + channel,URM_ENABLE_0_TX); + } + + return ret; +} + +int xr_usb_serial_set_loopback(struct xr_usb_serial *xr_usb_serial, int channel) +{ + int ret = 0; + xr_usb_serial_disable(xr_usb_serial); + + if((xr_usb_serial->DeviceProduct == 0x1410) || + (xr_usb_serial->DeviceProduct == 0x1412) || + (xr_usb_serial->DeviceProduct == 0x1414)) + { + switch (channel) + { + case 0: + ret = xr_usb_serial_set_reg_ext(xr_usb_serial,channel, + xr_usb_serial->reg_map.uart_loopback_addr,0x40); + break; + case 1: + ret = xr_usb_serial_set_reg_ext(xr_usb_serial,channel, + xr_usb_serial->reg_map.uart_loopback_addr,0x41); + break; + case 2: + ret = xr_usb_serial_set_reg_ext(xr_usb_serial,channel, + xr_usb_serial->reg_map.uart_loopback_addr,0x42); + break; + case 3: + ret = xr_usb_serial_set_reg_ext(xr_usb_serial,channel, + xr_usb_serial->reg_map.uart_loopback_addr,0x43); + break; + default: + break; + } + } + else if((xr_usb_serial->DeviceProduct == 0x1420)|| + (xr_usb_serial->DeviceProduct == 0x1422)|| + (xr_usb_serial->DeviceProduct == 0x1424)) + { + ret = xr_usb_serial_set_reg_ext(xr_usb_serial,channel, + xr_usb_serial->reg_map.uart_loopback_addr,0x07); + } + xr_usb_serial_enable(xr_usb_serial); + return ret; +} + +#define XR21V1414_WIDE_MODE_OFFSET 3 +#define XR21B142X_WIDE_MODE_TX_OFFSET 0x42 +#define XR21B142X_WIDE_MODE_RX_OFFSET 0x45 +/* XR2280x_FUNC_MGR_OFFSET will be included in xr_usb_serial_set_reg */ +#define XR21B140X_WIDE_MODE_TX_OFFSET 0x22 +#define XR21B140X_WIDE_MODE_RX_OFFSET 0x25 +int xr_usb_serial_set_wide_mode(struct xr_usb_serial *xr_usb_serial, int preciseflags) +{ + int ret = 0; + int channel = xr_usb_serial->channel; + xr_usb_serial_disable(xr_usb_serial); + if((xr_usb_serial->DeviceProduct&0xfff0) == 0x1400) + { + xr_usb_serial_set_reg(xr_usb_serial, XR21B140X_WIDE_MODE_TX_OFFSET, preciseflags); + xr_usb_serial_set_reg(xr_usb_serial, XR21B140X_WIDE_MODE_RX_OFFSET, preciseflags); + } + else if((xr_usb_serial->DeviceProduct == 0x1410)|| + (xr_usb_serial->DeviceProduct == 0x1412)|| + (xr_usb_serial->DeviceProduct == 0x1414)) + { + if(channel) channel--; + xr_usb_serial_set_reg_ext(xr_usb_serial, 0x66, channel*8 + XR21V1414_WIDE_MODE_OFFSET, preciseflags); + } + else if(xr_usb_serial->DeviceProduct == 0x1411) + { + xr_usb_serial_set_reg(xr_usb_serial,0xd02, preciseflags); + } + else if((xr_usb_serial->DeviceProduct == 0x1420)|| + (xr_usb_serial->DeviceProduct == 0x1422)|| + (xr_usb_serial->DeviceProduct == 0x1424)) + { + xr_usb_serial_set_reg(xr_usb_serial, XR21B142X_WIDE_MODE_TX_OFFSET, preciseflags); + xr_usb_serial_set_reg(xr_usb_serial, XR21B142X_WIDE_MODE_RX_OFFSET, preciseflags); + } + xr_usb_serial_enable(xr_usb_serial); + return ret; +} + +static int xr_usb_serial_tiocmget(struct xr_usb_serial *xr_usb_serial) +{ + short data; + int result; + result = xr_usb_serial_get_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_gpio_status_addr, &data); + //dev_info(&xr_usb_serial->control->dev, "xr_usb_serial_tiocmget uart_gpio_status_addr:0x%04x\n",data); + if (result) + return ((data & 0x8) ? 0: TIOCM_DTR) | ((data & 0x20) ? 0:TIOCM_RTS ) | ((data & 0x4) ? 0:TIOCM_DSR) | ((data & 0x1) ? 0 : TIOCM_RI) | ((data & 0x2) ? 0:TIOCM_CD) | ((data & 0x10) ? 0 : TIOCM_CTS); + else + return -EFAULT; +} + +static int xr_usb_serial_tiocmset(struct xr_usb_serial *xr_usb_serial, + unsigned int set, unsigned int clear) +{ + unsigned int newctrl = 0; + newctrl = xr_usb_serial->ctrlout; + + set = (set & TIOCM_DTR ? XR_USB_SERIAL_CTRL_DTR : 0) | (set & TIOCM_RTS ? XR_USB_SERIAL_CTRL_RTS : 0); + + clear = (clear & TIOCM_DTR ? XR_USB_SERIAL_CTRL_DTR : 0) | (clear & TIOCM_RTS ? XR_USB_SERIAL_CTRL_RTS : 0); + + newctrl = (newctrl & ~clear) | set; + + if (xr_usb_serial->ctrlout == newctrl) + return 0; + + xr_usb_serial->ctrlout = newctrl; + + if (newctrl & XR_USB_SERIAL_CTRL_DTR) + xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_clr_addr, 0x08); + else + xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_set_addr, 0x08); + + if (newctrl & XR_USB_SERIAL_CTRL_RTS) + xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_clr_addr, 0x20); + else + xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_set_addr, 0x20); + + return 0; +} + +static struct reg_addr_map xr21b140x_reg_map; +static struct reg_addr_map xr21b1411_reg_map; +static struct reg_addr_map xr21v141x_reg_map; +static struct reg_addr_map xr21b142x_reg_map; + +static void init_xr21b140x_reg_map(void) +{ + xr21b140x_reg_map.uart_enable_addr = 0x00; + xr21b140x_reg_map.uart_format_addr = 0x05; + xr21b140x_reg_map.uart_flow_addr = 0x06; + xr21b140x_reg_map.uart_loopback_addr = 0x16; + xr21b140x_reg_map.uart_xon_char_addr = 0x07; + xr21b140x_reg_map.uart_xoff_char_addr = 0x08; + xr21b140x_reg_map.uart_gpio_mode_addr = 0x0c; + xr21b140x_reg_map.uart_gpio_dir_addr = 0x0d; + xr21b140x_reg_map.uart_gpio_set_addr = 0x0e; + xr21b140x_reg_map.uart_gpio_clr_addr = 0x0f; + xr21b140x_reg_map.uart_gpio_status_addr = 0x10; + xr21b140x_reg_map.tx_break_addr = 0x0a; + xr21b140x_reg_map.uart_custom_driver = 0x41; +} + +static void init_xr21b1411_reg_map(void) +{ + xr21b1411_reg_map.uart_enable_addr = 0xc00; + xr21b1411_reg_map.uart_flow_addr = 0xc06; + xr21b1411_reg_map.uart_loopback_addr = 0xc16; + xr21b1411_reg_map.uart_xon_char_addr = 0xc07; + xr21b1411_reg_map.uart_xoff_char_addr = 0xc08; + xr21b1411_reg_map.uart_gpio_mode_addr = 0xc0c; + xr21b1411_reg_map.uart_gpio_dir_addr = 0xc0d; + xr21b1411_reg_map.uart_gpio_set_addr = 0xc0e; + xr21b1411_reg_map.uart_gpio_clr_addr = 0xc0f; + xr21b1411_reg_map.uart_gpio_status_addr = 0xc10; + xr21b1411_reg_map.tx_break_addr = 0xc0a; + xr21b1411_reg_map.uart_custom_driver = 0x20d; +} + +static void init_xr21v141x_reg_map(void) +{ + xr21v141x_reg_map.uart_enable_addr = 0x03; + xr21v141x_reg_map.uart_format_addr = 0x0b; + xr21v141x_reg_map.uart_flow_addr = 0x0c; + xr21v141x_reg_map.uart_loopback_addr = 0x12; + xr21v141x_reg_map.uart_xon_char_addr = 0x10; + xr21v141x_reg_map.uart_xoff_char_addr = 0x11; + xr21v141x_reg_map.uart_gpio_mode_addr = 0x1a; + xr21v141x_reg_map.uart_gpio_dir_addr = 0x1b; + xr21v141x_reg_map.uart_gpio_set_addr = 0x1d; + xr21v141x_reg_map.uart_gpio_clr_addr = 0x1e; + xr21v141x_reg_map.uart_gpio_status_addr = 0x1f; + xr21v141x_reg_map.tx_break_addr = 0x14; +} + +static void init_xr21b142x_reg_map(void) +{ + xr21b142x_reg_map.uart_enable_addr = 0x00; + xr21b142x_reg_map.uart_flow_addr = 0x06; + xr21b142x_reg_map.uart_loopback_addr = 0x16; + xr21b142x_reg_map.uart_xon_char_addr = 0x07; + xr21b142x_reg_map.uart_xoff_char_addr = 0x08; + xr21b142x_reg_map.uart_gpio_mode_addr = 0x0c; + xr21b142x_reg_map.uart_gpio_dir_addr = 0x0d; + xr21b142x_reg_map.uart_gpio_set_addr = 0x0e; + xr21b142x_reg_map.uart_gpio_clr_addr = 0x0f; + xr21b142x_reg_map.uart_gpio_status_addr = 0x10; + xr21b142x_reg_map.tx_break_addr = 0x0a; + xr21b142x_reg_map.uart_custom_driver = 0x60; + xr21b142x_reg_map.uart_low_latency = 0x46; +} + +int xr_usb_serial_pre_setup(struct xr_usb_serial *xr_usb_serial) +{ + int ret = 0; + + init_xr21b140x_reg_map(); + init_xr21b1411_reg_map(); + init_xr21v141x_reg_map(); + init_xr21b142x_reg_map(); + if((xr_usb_serial->DeviceProduct&0xfff0) == 0x1400) + { + memcpy(&(xr_usb_serial->reg_map),&xr21b140x_reg_map,sizeof(struct reg_addr_map)); + } + else if(xr_usb_serial->DeviceProduct == 0x1411) + { + memcpy(&(xr_usb_serial->reg_map),&xr21b1411_reg_map,sizeof(struct reg_addr_map)); + } + else if((xr_usb_serial->DeviceProduct == 0x1410)|| + (xr_usb_serial->DeviceProduct == 0x1412)|| + (xr_usb_serial->DeviceProduct == 0x1414)) + { + memcpy(&(xr_usb_serial->reg_map),&xr21v141x_reg_map,sizeof(struct reg_addr_map)); + } + else if((xr_usb_serial->DeviceProduct == 0x1420)|| + (xr_usb_serial->DeviceProduct == 0x1422)|| + (xr_usb_serial->DeviceProduct == 0x1424)) + { + memcpy(&(xr_usb_serial->reg_map),&xr21b142x_reg_map,sizeof(struct reg_addr_map)); + } + else + { + ret = -1; + } + if(xr_usb_serial->reg_map.uart_custom_driver) + xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_custom_driver, 1); + + xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_mode_addr, 0); + xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_dir_addr, 0x28); + xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_set_addr, UART_GPIO_SET_DTR | UART_GPIO_SET_RTS); + + return ret; +} diff --git a/package/kernel/xr-usb-serial/src/xr_usb_serial_ioctl.h b/package/kernel/xr-usb-serial/src/xr_usb_serial_ioctl.h new file mode 100644 index 000000000..eb7cd4b7e --- /dev/null +++ b/package/kernel/xr-usb-serial/src/xr_usb_serial_ioctl.h @@ -0,0 +1,35 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#define XR_USB_SERIAL_IOC_MAGIC 'v' + +#define XR_USB_SERIAL_GET_REG _IOWR(XR_USB_SERIAL_IOC_MAGIC, 1, int) +#define XR_USB_SERIAL_SET_REG _IOWR(XR_USB_SERIAL_IOC_MAGIC, 2, int) +#define XR_USB_SERIAL_SET_ADDRESS_MATCH _IO(XR_USB_SERIAL_IOC_MAGIC, 3) +#define XR_USB_SERIAL_SET_PRECISE_FLAGS _IO(XR_USB_SERIAL_IOC_MAGIC, 4) +#define XR_USB_SERIAL_TEST_MODE _IO(XR_USB_SERIAL_IOC_MAGIC, 5) +#define XR_USB_SERIAL_LOOPBACK _IO(XR_USB_SERIAL_IOC_MAGIC, 6) +#define XR_USB_SERIAL_SET_GPIO_MODE_REG _IO(XR_USB_SERIAL_IOC_MAGIC, 9) +#define XR_USB_SERIAL_GET_GPIO_MODE_REG _IO(XR_USB_SERIAL_IOC_MAGIC, 10) +#define XRIOC_SET_ANY_BAUD_RATE _IO(XR_USB_SERIAL_IOC_MAGIC, 11) +#define XRIOC_SET_PRECISE_FLAGS _IO(XR_USB_SERIAL_IOC_MAGIC, 12) + +#define VZ_ADDRESS_UNICAST_S 0 +#define VZ_ADDRESS_BROADCAST_S 8 +#define VZ_ADDRESS_MATCH(U, B) (0x8000000 | ((B) << VZ_ADDRESS_BROADCAST_S) | ((U) << VZ_ADDRESS_UNICAST_S)) +#define VZ_ADDRESS_MATCH_DISABLE 0 diff --git a/package/lean/autocore/files/x86/autocore b/package/lean/autocore/files/x86/autocore index 46cece8bb..2ad0a2ea8 100755 --- a/package/lean/autocore/files/x86/autocore +++ b/package/lean/autocore/files/x86/autocore @@ -5,71 +5,35 @@ START=99 start() { - sysctl -w net.netfilter.nf_conntrack_max=6553500 >/dev/null - sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=7440 >/dev/null - sysctl -w net.netfilter.nf_conntrack_udp_timeout=60 >/dev/null - sysctl -w net.netfilter.nf_conntrack_udp_timeout_stream=180 >/dev/null - sysctl -w fs.nr_open=65535000 >/dev/null - sysctl -w net.core.netdev_budget=5000 >/dev/null - sysctl -w net.core.netdev_budget_usecs=50000 >/dev/null - sysctl -w net.netfilter.nf_conntrack_max=629536 >/dev/null - sysctl -w net.netfilter.nf_conntrack_buckets=65535 >/dev/null - sysctl -w net.core.somaxconn=32768 >/dev/null - sysctl -w net.core.netdev_max_backlog=52768 >/dev/null - + rfc=4096 + cc=$(grep -c processor /proc/cpuinfo) + rsfe=$(echo $cc*$rfc | bc) + sysctl -w net.core.rps_sock_flow_entries=$rsfe >/dev/null + for fileRps in $(ls /sys/class/net/eth*/queues/rx-*/rps_cpus) + do + echo $cc > $fileRps + done + + for fileRfc in $(ls /sys/class/net/eth*/queues/rx-*/rps_flow_cnt) + do + echo $rfc > $fileRfc + done + + uci set network.@globals[0].packet_steering=1 + uci commit network + a=$(cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq) b=$(echo -n ' : ') c=$(cat /proc/cpuinfo | grep 'core id' | sort -u | wc -l) d=$(echo -n ' Core ') e=$(cat /proc/cpuinfo | grep 'processor' | wc -l) f=$(echo -n ' Thread ') - g=$(cat /proc/cpuinfo |grep -m1 'model name'|awk -F: '{print $2$3}') + g=$(cat /tmp/sysinfo/model) h=${g}' - '${a}${b}${c}${d}${e}${f} mkdir -p /tmp/sysinfo echo $h > /tmp/sysinfo/model - uci get network.@globals[0].packet_steering >/dev/null 2>&1 - if [[ $? != 0 ]];then - sysctl -w net.core.rps_sock_flow_entries=32768 >/dev/null - for fileRps in $(ls /sys/class/net/eth*/queues/rx-*/rps_cpus) - do - echo 0 > $fileRps - done - - for fileRfc in $(ls /sys/class/net/eth*/queues/rx-*/rps_flow_cnt) - do - echo 0 > $fileRfc - done - [ -f /etc/index.htm ] && mv /etc/index.htm /usr/lib/lua/luci/view/admin_status/index.htm - exit 0 - fi - - rfc=4096 - cc=$(grep -c processor /proc/cpuinfo) - rsfe=$(echo $cc*$rfc | bc) - sysctl -w net.core.rps_sock_flow_entries=32768 >/dev/null - cflag="0" - cc=`expr $cc - 1` - for z in `seq $cc` - do - cflag="1${cflag}" - done - cc=`echo "ibase=2;obase=10000;$cflag"|bc` - - for fileRps in $(ls /sys/class/net/eth*/queues/rx-*/rps_cpus) - do - echo $cc > $fileRps - done - - for fileRfc in $(ls /sys/class/net/eth*/queues/rx-*/rps_flow_cnt) - do - echo $rfc > $fileRfc - done - - uci set network.@globals[0].packet_steering=1 - uci commit network - a=$(ip address | grep ^[0-9] | awk -F: '{print $2}' | sed "s/ //g" | grep '^[e]' | grep -v "@" | grep -v "\.") b=$(echo "$a" | wc -l) for i in $(seq 1 $b) @@ -82,9 +46,8 @@ start() ethtool -K $c tx-scatter-gather on >/dev/null 2>&1 ethtool -K $c gso on >/dev/null 2>&1 ethtool -K $c tso on >/dev/null 2>&1 - ethtool -K $c tso on sg on tx on >/dev/null 2>&1 ethtool -K $c ufo on >/dev/null 2>&1 done [ -f /etc/index.htm ] && mv /etc/index.htm /usr/lib/lua/luci/view/admin_status/index.htm -} \ No newline at end of file +} diff --git a/package/lean/ddns-scripts_aliyun/update_aliyun_com.sh b/package/lean/ddns-scripts_aliyun/update_aliyun_com.sh index 96d5ff49a..8bfeeb576 100755 --- a/package/lean/ddns-scripts_aliyun/update_aliyun_com.sh +++ b/package/lean/ddns-scripts_aliyun/update_aliyun_com.sh @@ -199,7 +199,7 @@ enable_domain() { # 获取子域名解析记录列表 describe_domain() { local count value; local ret=0 - aliyun_transfer "Action=DescribeSubDomainRecords" "SubDomain=${__HOST}.${__DOMAIN}" || write_log 14 "服务器通信失败" + aliyun_transfer "Action=DescribeSubDomainRecords" "SubDomain=${__HOST}.${__DOMAIN}" "DomainName=${__DOMAIN}" || write_log 14 "服务器通信失败" write_log 7 "获取到解析记录: $(cat "$DATFILE" 2> /dev/null)" json_cleanup; json_load "$(cat "$DATFILE" 2> /dev/null)" >/dev/null 2>&1 json_get_var count "TotalCount" diff --git a/package/kernel/r8125/Makefile b/package/lean/r8125/Makefile similarity index 100% rename from package/kernel/r8125/Makefile rename to package/lean/r8125/Makefile diff --git a/package/kernel/r8125/patches/010-config.patch b/package/lean/r8125/patches/010-config.patch similarity index 100% rename from package/kernel/r8125/patches/010-config.patch rename to package/lean/r8125/patches/010-config.patch diff --git a/package/kernel/r8125/patches/020-5.19-support.patch b/package/lean/r8125/patches/020-5.19-support.patch similarity index 100% rename from package/kernel/r8125/patches/020-5.19-support.patch rename to package/lean/r8125/patches/020-5.19-support.patch diff --git a/package/kernel/r8125/patches/030-add-LED-configuration-from-OF.patch b/package/lean/r8125/patches/030-add-LED-configuration-from-OF.patch similarity index 100% rename from package/kernel/r8125/patches/030-add-LED-configuration-from-OF.patch rename to package/lean/r8125/patches/030-add-LED-configuration-from-OF.patch diff --git a/package/kernel/r8152/Makefile b/package/lean/r8152/Makefile similarity index 100% rename from package/kernel/r8152/Makefile rename to package/lean/r8152/Makefile diff --git a/package/kernel/r8152/patches/010-5.19-support.patch b/package/lean/r8152/patches/010-5.19-support.patch similarity index 100% rename from package/kernel/r8152/patches/010-5.19-support.patch rename to package/lean/r8152/patches/010-5.19-support.patch diff --git a/package/kernel/r8152/patches/020-6.1-support.patch b/package/lean/r8152/patches/020-6.1-support.patch similarity index 100% rename from package/kernel/r8152/patches/020-6.1-support.patch rename to package/lean/r8152/patches/020-6.1-support.patch diff --git a/package/kernel/r8168/Makefile b/package/lean/r8168/Makefile similarity index 100% rename from package/kernel/r8168/Makefile rename to package/lean/r8168/Makefile diff --git a/package/kernel/r8168/patches/001-r8168-add-LED-configuration-from-OF.patch b/package/lean/r8168/patches/001-r8168-add-LED-configuration-from-OF.patch similarity index 100% rename from package/kernel/r8168/patches/001-r8168-add-LED-configuration-from-OF.patch rename to package/lean/r8168/patches/001-r8168-add-LED-configuration-from-OF.patch diff --git a/package/kernel/r8168/patches/020-5.19-support.patch b/package/lean/r8168/patches/020-5.19-support.patch similarity index 100% rename from package/kernel/r8168/patches/020-5.19-support.patch rename to package/lean/r8168/patches/020-5.19-support.patch diff --git a/package/kernel/r8168/patches/030-6.1-support.patch b/package/lean/r8168/patches/030-6.1-support.patch similarity index 100% rename from package/kernel/r8168/patches/030-6.1-support.patch rename to package/lean/r8168/patches/030-6.1-support.patch diff --git a/package/qat/firmware/quickassist-c2xxx/Config.in b/package/qat/firmware/quickassist-c2xxx/Config.in new file mode 100644 index 000000000..38dfae350 --- /dev/null +++ b/package/qat/firmware/quickassist-c2xxx/Config.in @@ -0,0 +1,9 @@ +menu "Configuration" + depends on PACKAGE_kmod-crypto-qat-c2xxx + +config CRYPTO_QAT_DEBUG + bool + default n + prompt "Build with debugging support enabled" + +endmenu diff --git a/package/qat/firmware/quickassist-c2xxx/Makefile b/package/qat/firmware/quickassist-c2xxx/Makefile new file mode 100644 index 000000000..2cb1ec3b7 --- /dev/null +++ b/package/qat/firmware/quickassist-c2xxx/Makefile @@ -0,0 +1,160 @@ +# +# Copyright (C) DL +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=quickassist-c2xxx + +PKG_VERSION:=1.5 +PKG_RELEASE:=2 + +PKG_SOURCE_VERSION:=1.5.l.1.13.0-19 +PKG_SOURCE:=qat$(PKG_SOURCE_VERSION).tar.gz +PKG_SOURCE_URL:=https://01.org/sites/default/files/downloads/intel-quickassist-technology/ +PKG_HASH:=afe8339edbbf05099e79c256191584aabf30b564f89a553b9585b2f8e18bee17 + +PKG_LICENSE:=GPL v3 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +PKG_BUILD_PARALLEL:=0 + +define Package/quickassist-c2xxx + SECTION:=firmware + CATEGORY:=Firmware + TITLE:=Intel Quick Assist meta-package for c2xxx + DEPENDS:= \ + @TARGET_x86_64 \ + @LINUX_4_14 \ + +libopenssl \ + +kmod-crypto-qat-c2xxx \ + +kmod-crypto-qat-c2xxx-usdm +endef + +define Package/quickassist-c2xxx/config + depends on !quickassist-c3xxx-enabled + config quickassist-c2xxx-enabled + bool + default y if PACKAGE_quickassist-c2xxx + default n +endef + +define Package/quickassist-c2xxx/description + Intel Quick Assist v1.5 utilities and firmware for c2xxx series SoCs +endef + +# +# QAT 1.5 kernel driver +# + +define KernelPackage/crypto-qat-c2xxx + SUBMENU:=Cryptographic API modules + TITLE:=Intel Quick Assist Technology Drivers + DEPENDS:= \ + @TARGET_x86_64 \ + @LINUX_4_14 \ + +libc \ + +libpthread \ + +libopenssl \ + +kmod-crypto-manager \ + +kmod-crypto-cbc \ + +kmod-crypto-sha1 \ + +kmod-crypto-sha256 \ + +kmod-crypto-sha512 + FILES:=$(PKG_BUILD_DIR)/build/icp_qa_al.ko +endef + +define KernelPackage/crypto-qat-c2xxx/description + Kernel driver for Intel Quick Assist Technology c2xxx +endef + +define KernelPackage/crypto-qat-c2xxx/config + depends on quickassist-c2xxx-enabled + source "$(SOURCE)/Config.in" +endef + +# +# QAT 1.7 contiguous pinned memory driver +# + +define KernelPackage/crypto-qat-c2xxx-usdm + SUBMENU:=Cryptographic API modules + TITLE:=Quick Assist Pinned Memory Driver + DEPENDS:= \ + @TARGET_x86_64 \ + @LINUX_4_14 + FILES:=$(PKG_BUILD_DIR)/build/usdm_drv.ko + AUTOLOAD:=$(call AutoProbe,usdm_drv) +endef + +define KernelPackage/crypto-qat-c2xxx-usdm/config + depends on quickassist-c2xxx-enabled +endef + +define KernelPackage/crypto-qat-c2xxx-usdm/description + Contiguous pinned memory driver for Intel Quick Assist Technology +endef + +ICP_ARCH = x86_64 +MAKE_PATH = quickassist +MAKE_FLAGS = ARCH_USER="$(ICP_ARCH)" + +MAKE_VARS += ICP_ROOT="$(PKG_BUILD_DIR)" \ + CROSS_COMPILE="$(KERNEL_CROSS)" \ + KERNEL_SOURCE_ROOT="$(LINUX_DIR)" \ + MACHINE="$(ICP_ARCH)" \ + ICP_BUILD_OUTPUT="$(PKG_BUILD_DIR)/build" \ + ICP_ENV_DIR="$(PKG_BUILD_DIR)/quickassist/build_system/build_files/env_files" \ + ICP_BUILDSYSTEM_PATH="$(PKG_BUILD_DIR)/quickassist/build_system" \ + ICP_TOOLS_TARGET="accelcomp" \ + ICP_NONBLOCKING_PARTIALS_PERFORM="1" \ + ICP_ARCH_USER="$(ICP_ARCH)" \ + LIB_SHARED_FLAGS="-L$(STAGING_DIR)/usr/lib" \ + LD_LIBRARY_PATH="$(PKG_BUILD_DIR)/build" + +define Build/Prepare + (mkdir -p '$(PKG_BUILD_DIR)' && zcat '$(DL_DIR)/$(PKG_SOURCE)' | tar -C '$(PKG_BUILD_DIR)' -xf -) + $(Build/Patch) +endef + +define Build/Compile + $(call Build/Compile/Default) + $(call Build/Compile/Default, -C $(PKG_BUILD_DIR)/quickassist/lookaside/access_layer/src/sample_code perf_all) +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include + $(INSTALL_DIR) $(1)/usr/lib + $(INSTALL_DIR) $(1)/usr/icp/quickassist + $(INSTALL_DIR) $(1)/usr/icp/build + $(CP) $(PKG_BUILD_DIR)/build/lib*.{a,so*} $(1)/usr/lib/ + $(CP) $(PKG_BUILD_DIR)/quickassist/include/{*.h,dc,lac} $(1)/usr/include + $(CP) $(PKG_BUILD_DIR)/quickassist/lookaside/access_layer/include/*.h $(1)/usr/include + $(CP) $(PKG_BUILD_DIR)/quickassist $(1)/usr/icp + $(CP) $(PKG_BUILD_DIR)/build $(1)/usr/icp +endef + +define Package/quickassist/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/lib/firmware + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_DIR) $(1)/usr/share/quickassist/QAT1.5/config + $(CP) $(PKG_BUILD_DIR)/quickassist/config/* $(1)/usr/share/quickassist/QAT1.5/config + $(CP) $(PKG_BUILD_DIR)/build/adf_ctl $(1)/usr/sbin/adf_ctl + $(CP) $(PKG_BUILD_DIR)/quickassist/adf/build/linux_2.6/icp_gige_watchdog $(1)/usr/sbin/icp_gige_watchdog + $(CP) $(PKG_BUILD_DIR)/build/lib*.{a,so*} $(1)/lib/ + $(CP) $(PKG_BUILD_DIR)/build/*.bin $(1)/lib/firmware/ + $(CP) ./files/qat.init $(1)/etc/init.d/qat + $(CP) ./files/qat_watchdog.init $(1)/etc/init.d/qat_watchdog + $(CP) ./files/c2xxx_qa_dev0_single_ae.conf $(1)/etc/c2xxx_qa_dev0.conf +endef + +$(eval $(call BuildPackage,quickassist-c2xxx)) +$(eval $(call KernelPackage,crypto-qat-c2xxx)) +$(eval $(call KernelPackage,crypto-qat-c2xxx-usdm)) diff --git a/package/qat/firmware/quickassist-c2xxx/files/c2xxx_qa_dev0_single_ae.conf b/package/qat/firmware/quickassist-c2xxx/files/c2xxx_qa_dev0_single_ae.conf new file mode 100644 index 000000000..3b0acd6b9 --- /dev/null +++ b/package/qat/firmware/quickassist-c2xxx/files/c2xxx_qa_dev0_single_ae.conf @@ -0,0 +1,175 @@ +######################################################################### +# +# @par +# # This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2020 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2020 Intel Corporation. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +######################################################################### + +######################################################## +# General Section +############################################## + +[GENERAL] +ServicesEnabled = cy0 + +# Use version 2 of the config file +ConfigVersion = 2 + +# Look Aside Cryptographic Configuration +cyHmacAuthMode = 1 + +# Firmware Location Configuration +Firmware_MofPath = mof_firmware_c2xxx.bin +Firmware_MmpPath = mmp_firmware_c2xxx.bin + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 64 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +#Debug feature, if set to 1 it enables additional entries in /proc filesystem +ProcDebug = 1 + + +####################################################### +# Wireless Section +####################################################### +[WIRELESS] +NumProcesses = 0 + +####################################################### +# +# Logical Instances Section +# A logical instance allows each address domain +# (kernel space and individual user space processes) +# to configure rings (i.e. hardware assisted queues) +# to be used by that address domain and to define the +# behavior of that ring. +# +# The address domains are in the following format +# - For kernel address domains +# [KERNEL] +# - For user process address domains +# [xxxxx] +# Where xxxxx may be any ascii value which uniquely identifies +# the user mode process. +# To allow the driver correctly configure the +# logical instances associated with this user process, +# the process must call the icp_sal_userStart(...) +# passing the xxxxx string during process initialisation. +# When the user space process is finish it must call +# icp_sal_userStop(...) to free resources. +# NumProcesses will indicate the maximum number of processes +# that can call icp_sal_userStart on this instance. +# Warning: the ressources are preallocated: if NumProcesses +# is too high, the driver will fail to load +# +# Items configurable by a logical instance are: +# - Name of the logical instance +# - The accelerator associated with this logical +# instance +# - The core the instance is affinitized to (optional) +# +# Note: Logical instances may not share the same ring, but +# may share a ring bank. +# +# The format of the logical instances are: +# - For crypto: +# CyName = "xxxx" +# CyAcceleratorNumber = 0-1 +# CyCoreAffinity = 0-7 +# +# Note: for user space processes, a list of values can be specified for +# the core affinity: for example +# Cy0CoreAffinity = 0,2,4 +# +# Where: +# - n is the number of this logical instance starting at 0. +# - xxxx may be any ascii value which identifies the logical instance. +# +######################################################## + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 0 + +############################################## +# Compression multi thread/process section +############################################## +[SHIM] +NumberCyInstances = 1 +NumProcesses = 8 +LimitDevAccess = 1 + +# Crypto - User space +Cy0Name = "UserCY0" +Cy0AcceleratorNumber = 0 +Cy0IsPolled = 1 +Cy0CoreAffinity = 0 diff --git a/package/qat/firmware/quickassist-c2xxx/files/qat.init b/package/qat/firmware/quickassist-c2xxx/files/qat.init new file mode 100755 index 000000000..cf737bfbf --- /dev/null +++ b/package/qat/firmware/quickassist-c2xxx/files/qat.init @@ -0,0 +1,140 @@ +#!/bin/sh /etc/rc.common + +# Adapted from Intel QAT1.5 qat_service. Portions copyright Intel Corporation + +################################################################# +# +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2013 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2013 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT1.5.L.1.10.0-80 +# +################################################################# + +# qat Start/Stop the Intel QAT. +# +# description: modprobe the QAT icp_qa_al.ko, which loads dependant \ +# modules, before calling the user space \ +# utility to pass configuration parameters + +START=29 +STOP=99 + +PROG=/usr/sbin/adf_ctl +KMOD=icp_qa_al +NETKEY=icp_qat_netkey.ko + +EXTRA_COMMANDS="status" +EXTRA_HELP=" status Show the status of the qat device" + +status() { + + ${PROG} status + if [ "$?" -ne 0 ] + then + echo "No devices found. Please start the driver using:" + echo "$0 start" + fi + +} + +start() { + + # First check if the modules are already installed + # install them as necessary and if they are LKMs + # and not built-in kernel modules + + if [ `lsmod | grep -c "sha512"` == 0 ]; then + if [ `cat /proc/kallsyms |grep -c sha512_generic` == 0 ]; then + `modprobe sha512` + fi + fi + + if [ `lsmod | grep -c "sha256"` == 0 ]; then + if [ `cat /proc/kallsyms |grep -c sha256_generic` == 0 ]; then + `modprobe sha256` + fi + fi + + lsmod | grep ${KMOD} >/dev/null 2>&1 || modprobe ${KMOD} + + # Check device status, try to turn it on only if driver is loaded + + ${PROG} $2 status | grep state=down >/dev/null 2>&1 + if [ $? = 0 ]; then + ${PROG} $2 up + fi + + # lsmod | grep ${NETKEY} >/dev/null 2>&1 || modprobe ${NETKEY} 2> /dev/null + + # Show device status + + ${PROG} $2 status +} + +stop() { + + ${PROG} $2 down + +} + +restart() { + + ${PROG} $2 down && ${PROG} $2 up + +} + diff --git a/package/qat/firmware/quickassist-c2xxx/files/qat_watchdog.init b/package/qat/firmware/quickassist-c2xxx/files/qat_watchdog.init new file mode 100755 index 000000000..24411f992 --- /dev/null +++ b/package/qat/firmware/quickassist-c2xxx/files/qat_watchdog.init @@ -0,0 +1,119 @@ +#!/bin/bash /etc/rc.common + +################################################################# +# +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2013 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2013 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT1.5.L.1.10.0-80 +# +################################################################# + + + +START=99 +STOP=99 + +PROG=/usr/sbin/icp_gige_watchdog +PID="`ps | grep ${PROG} | grep -v grep | awk '{print $1}'`" + +EXTRA_COMMANDS="status" +EXTRA_HELP=" status Show the status of the qat device" + +status() { + + if [ -z "$PID" ] + then + echo "${PROG} not running" + else + echo "${PROG} running: ${PID}" + fi + +} + +start() { + + if [ -z "$PID" ] + then + ${PROG} & + else + echo "Already running pid: ${PID}" + fi + +} + +stop() { + + if [ -z "$PID" ] + then + echo "${PROG} not running" + else + kill -USR1 ${PID} + fi + +} + +restart() { + + stop + start + +} + + + + diff --git a/package/qat/firmware/quickassist-c2xxx/patches/0001-intel-kernel-v3-to-v4.patch b/package/qat/firmware/quickassist-c2xxx/patches/0001-intel-kernel-v3-to-v4.patch new file mode 100644 index 000000000..b6a2e5419 --- /dev/null +++ b/package/qat/firmware/quickassist-c2xxx/patches/0001-intel-kernel-v3-to-v4.patch @@ -0,0 +1,360 @@ +--- a/quickassist/adf/accel_mgr/src/adf_cfg.c ++++ b/quickassist/adf/accel_mgr/src/adf_cfg.c +@@ -545,9 +545,10 @@ CpaStatus adf_cfgAddKeyValueParam(icp_ac + } + else if(ADF_HEX == type) + { +- value_addr = (Cpa64U *)val; +- snprintf(pKeyValue->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES, +- "0x%p", value_addr); ++// value_addr = (Cpa64U *)val; ++// snprintf(pKeyValue->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ++// "0x%p", value_addr); ++ snprintf(pKeyValue->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES,"0x%lx", (uintptr_t)val); + } + else + { +--- a/quickassist/adf/accelengine/src/adf_ae.c ++++ b/quickassist/adf/accelengine/src/adf_ae.c +@@ -222,6 +222,7 @@ CpaStatus adf_aeFwLoad(icp_accel_dev_t * + /* Get the UoF FW and Map the memory to the AEs */ + status = adf_aefwGetFirmware(pAccelDev, ADF_FW_UOF_TYPE, &addr, &size); + ICP_CHECK_STATUS(status); ++ + /* load ucode for patching, ucode_map */ + status = adf_aeUcodeMap(pAccelDev, addr, size); + if (CPA_STATUS_SUCCESS != status) +--- a/quickassist/adf/accelengine/src/adf_ae_fw.c ++++ b/quickassist/adf/accelengine/src/adf_ae_fw.c +@@ -147,7 +147,6 @@ CpaStatus adf_aefwLoadFirmware(icp_accel + return CPA_STATUS_FAIL; + } + ICP_MEMCPY(pUofFwAddr, pFwAddr, fwSize); +- + /* + * Add the local copies to the config table. + * When the memory address is needed again it can be queried from +@@ -356,14 +355,13 @@ CpaStatus adf_aefwGetFirmware(icp_accel_ + status_addr = icp_adf_cfgGetParamValue(pAccelDev, INTERNAL_SEC, + ICP_CFG_UOF_ADDRESS_KEY, config_value); + *pAddr = (void *)ICP_STRTOUL(config_value, NULL, ADF_CFG_BASE_HEX); +- status_size = icp_adf_cfgGetParamValue(pAccelDev, INTERNAL_SEC, ++ status_size = icp_adf_cfgGetParamValue(pAccelDev, INTERNAL_SEC, + ICP_CFG_UOF_SIZE_BYTES_KEY, config_value); + *pSize = (Cpa32U)ICP_STRTOUL(config_value, NULL, ADF_CFG_BASE_DEC); + break; + case ADF_FW_MMP_TYPE: + status_addr = icp_adf_cfgGetParamValue(pAccelDev, INTERNAL_SEC, + ICP_CFG_MMP_ADDRESS_KEY, config_value); +- *pAddr = (void *)ICP_STRTOUL(config_value, NULL, ADF_CFG_BASE_HEX); + status_size = icp_adf_cfgGetParamValue(pAccelDev, INTERNAL_SEC, + ICP_CFG_MMP_SIZE_BYTES_KEY, config_value); + *pSize = (Cpa32U)ICP_STRTOUL(config_value, NULL, ADF_CFG_BASE_DEC); +--- a/quickassist/adf/drivers/ACCELDEV/linux/src/adf_acceldev_drv.c ++++ b/quickassist/adf/drivers/ACCELDEV/linux/src/adf_acceldev_drv.c +@@ -911,7 +911,7 @@ int adf_restore_dev(icp_accel_dev_t *acc + ADF_ERROR("Can not issue secondary bus reset\n"); + ADF_ERROR("Trying FLR\n"); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) +- ret = __pci_reset_function(pdev); ++ ret = pci_reset_function(pdev); + if (ret) { + ADF_ERROR("Could not reset device\n"); + return ret; +--- a/quickassist/adf/drivers/ACCELDEV/linux/src/adf_acceldev_isr.c ++++ b/quickassist/adf/drivers/ACCELDEV/linux/src/adf_acceldev_isr.c +@@ -214,7 +214,7 @@ STATIC int adf_enable_msix(icp_accel_dev + (hw_data->msix.aeVectorStart - hw_data->msix.banksVectorNum); + } + +- stat = pci_enable_msix(pci_dev_info->pDev, ++ stat = pci_enable_msix_exact(pci_dev_info->pDev, + pci_dev_info->msixEntries.value, + msix_num_entries); + if (SUCCESS != stat){ +--- a/quickassist/adf/drivers/common/linux/src/adf_dev_csr.c ++++ b/quickassist/adf/drivers/common/linux/src/adf_dev_csr.c +@@ -80,6 +80,7 @@ + #include "adf_dev_csr.h" + #include "adf_platform.h" + #include ++#include + + #define ADF_DEV_CSR_NAME ("icp_dev_csr") + #define ADF_DEV_CSR_MAX_MINOR (255) +--- a/quickassist/adf/drivers/common/linux/src/adf_dev_ring.c ++++ b/quickassist/adf/drivers/common/linux/src/adf_dev_ring.c +@@ -87,6 +87,7 @@ + #include "icp_adf_init.h" + #include "icp_adf_cfg.h" + #include "adf_proc_debug.h" ++#include + + #define ADF_DEV_RING_NAME ("icp_dev_ring") + #define ADF_DEV_RING_MAX_MINOR (255) +--- a/quickassist/adf/drivers/common/linux/src/adf_gige_wd_drv.c ++++ b/quickassist/adf/drivers/common/linux/src/adf_gige_wd_drv.c +@@ -76,6 +76,8 @@ + #include "adf_platform.h" + #include + #include ++#include ++ + /* Character Device Driver Name */ + #define DEVICE_NAME "icp_adf_gige_wd" + #define COMPLETION_TIME 5000 +--- a/quickassist/adf/drivers/common/linux/src/adf_proc_debug.c ++++ b/quickassist/adf/drivers/common/linux/src/adf_proc_debug.c +@@ -132,17 +132,13 @@ static int adf_debug_show(struct seq_fil + { + debug_file_info_t* file_info = sfile->private; + if (file_info && file_info->seq_read && file_info->page) { +- int ret = 0, old_offset = file_info->offset; +- file_info->offset = +- file_info->seq_read(file_info->private_data, +- file_info->page, PAGE_SIZE - 1, +- file_info->offset); +- ret = seq_puts(sfile, (char*)file_info->page); +- if (ret) { +- /* run out of space - need to reprint */ +- file_info->offset = old_offset; +- } ++ file_info->offset = ++ file_info->seq_read(file_info->private_data, ++ file_info->page, PAGE_SIZE - 1, ++ file_info->offset); ++ seq_puts(sfile, (char*)file_info->page); + } ++ + return 0; + } + +--- a/quickassist/adf/include/icp_adf_transport_dp.h ++++ b/quickassist/adf/include/icp_adf_transport_dp.h +@@ -79,7 +79,7 @@ + * Data plain support function - returns the pointer to next message on the ring + * or NULL if there is not enough space. + */ +-inline void icp_adf_getQueueMemory(icp_comms_trans_handle trans_handle, ++void icp_adf_getQueueMemory(icp_comms_trans_handle trans_handle, + Cpa32U numberRequests, + void** pCurrentQatMsg); + /* +@@ -87,7 +87,7 @@ inline void icp_adf_getQueueMemory(icp_c + * Data plain support function - returns the pointer to next message on the ring + * or NULL if there is not enough space - it also updates the shadow tail copy. + */ +-inline void icp_adf_getSingleQueueAddr(icp_comms_trans_handle trans_handle, ++void icp_adf_getSingleQueueAddr(icp_comms_trans_handle trans_handle, + void** pCurrentQatMsg); + + /* +@@ -95,26 +95,26 @@ inline void icp_adf_getSingleQueueAddr(i + * Data plain support function - increments the tail pointer and returns + * the pointer to next message on the ring. + */ +-inline void icp_adf_getQueueNext(icp_comms_trans_handle trans_handle, ++void icp_adf_getQueueNext(icp_comms_trans_handle trans_handle, + void** pCurrentQatMsg); + + /* + * icp_adf_updateQueueTail + * Data plain support function - Writes the tail shadow copy to the device. + */ +-inline void icp_adf_updateQueueTail(icp_comms_trans_handle trans_handle); ++void icp_adf_updateQueueTail(icp_comms_trans_handle trans_handle); + + /* + * icp_adf_isRingEmpty + * Data plain support function - check if the ring is empty + */ +-inline CpaBoolean icp_adf_isRingEmpty(icp_comms_trans_handle trans_handle); ++CpaBoolean icp_adf_isRingEmpty(icp_comms_trans_handle trans_handle); + + /* + * icp_adf_pollQueue + * Data plain support function - Poll messages from the queue. + */ +-inline CpaStatus icp_adf_pollQueue(icp_comms_trans_handle trans_handle, ++CpaStatus icp_adf_pollQueue(icp_comms_trans_handle trans_handle, + Cpa32U response_quota); + + /* +@@ -123,6 +123,6 @@ inline CpaStatus icp_adf_pollQueue(icp_c + * send. This should only be called on request rings. If the function returns + * true then it is ok to call icp_adf_updateQueueTail() function on this ring. + */ +-inline CpaBoolean icp_adf_queueDataToSend(icp_comms_trans_handle trans_hnd); ++CpaBoolean icp_adf_queueDataToSend(icp_comms_trans_handle trans_hnd); + + #endif /* ICP_ADF_TRANSPORT_DP_H */ +--- a/quickassist/adf/include/icp_platform_linux.h ++++ b/quickassist/adf/include/icp_platform_linux.h +@@ -90,7 +90,7 @@ + + #include + #include +-#include ++#include + + #include "Osal.h" + +--- a/quickassist/adf/user/user_proxy/src/adf_user_ETring_mgr_dp.c ++++ b/quickassist/adf/user/user_proxy/src/adf_user_ETring_mgr_dp.c +@@ -84,7 +84,7 @@ + * Data plain support function - returns the pointer to next message on the ring + * or NULL if there is not enough space. + */ +-inline void icp_adf_getQueueMemory(icp_comms_trans_handle trans_hnd, ++void icp_adf_getQueueMemory(icp_comms_trans_handle trans_hnd, + Cpa32U numberRequests, + void** pCurrentQatMsg) + { +@@ -114,7 +114,7 @@ inline void icp_adf_getQueueMemory(icp_c + * Data plane support function - returns the pointer to next message on the ring + * or NULL if there is not enough space - it also updates the shadow tail copy. + */ +-inline void icp_adf_getSingleQueueAddr(icp_comms_trans_handle trans_hnd, ++void icp_adf_getSingleQueueAddr(icp_comms_trans_handle trans_hnd, + void** pCurrentQatMsg) + { + adf_dev_ring_handle_t *pRingHandle = (adf_dev_ring_handle_t *)trans_hnd; +@@ -147,7 +147,7 @@ inline void icp_adf_getSingleQueueAddr(i + * Data plain support function - increments the tail pointer and returns + * the pointer to next message on the ring. + */ +-inline void icp_adf_getQueueNext(icp_comms_trans_handle trans_hnd, ++void icp_adf_getQueueNext(icp_comms_trans_handle trans_hnd, + void** pCurrentQatMsg) + { + adf_dev_ring_handle_t *pRingHandle = (adf_dev_ring_handle_t *)trans_hnd; +@@ -168,7 +168,7 @@ inline void icp_adf_getQueueNext(icp_com + * icp_adf_updateQueueTail + * Data plain support function - Writes the tail shadow copy to the device. + */ +-inline void icp_adf_updateQueueTail(icp_comms_trans_handle trans_hnd) ++void icp_adf_updateQueueTail(icp_comms_trans_handle trans_hnd) + { + adf_dev_ring_handle_t *pRingHandle = (adf_dev_ring_handle_t *)trans_hnd; + icp_accel_dev_t *accel_dev = (icp_accel_dev_t*) pRingHandle->accel_dev; +@@ -183,7 +183,7 @@ inline void icp_adf_updateQueueTail(icp_ + * icp_adf_isRingEmpty + * Data plain support function - check if the ring is empty + */ +-inline CpaBoolean icp_adf_isRingEmpty(icp_comms_trans_handle trans_hnd) ++CpaBoolean icp_adf_isRingEmpty(icp_comms_trans_handle trans_hnd) + { + Cpa32U mask = 0; + adf_dev_ring_handle_t *pRingHandle = (adf_dev_ring_handle_t *)trans_hnd; +@@ -205,7 +205,7 @@ inline CpaBoolean icp_adf_isRingEmpty(ic + * * icp_adf_pollQueue + * * Data plain support function - Poll messages from the queue. + * */ +-inline CpaStatus icp_adf_pollQueue(icp_comms_trans_handle trans_hnd, ++CpaStatus icp_adf_pollQueue(icp_comms_trans_handle trans_hnd, + Cpa32U response_quota) + { + adf_dev_ring_handle_t *pRingHandle = (adf_dev_ring_handle_t *)trans_hnd; +@@ -260,7 +260,7 @@ inline CpaStatus icp_adf_pollQueue(icp_c + * send. This should only be called on request rings. If the function returns + * true then it is ok to call icp_adf_updateQueueTail() function on this ring. + */ +-inline CpaBoolean icp_adf_queueDataToSend(icp_comms_trans_handle trans_hnd) ++CpaBoolean icp_adf_queueDataToSend(icp_comms_trans_handle trans_hnd) + { + adf_dev_ring_handle_t *ringData = (adf_dev_ring_handle_t *)trans_hnd; + icp_accel_dev_t *accel_dev = (icp_accel_dev_t*) ringData->accel_dev; +--- a/quickassist/build_system/build_files/OS/linux_2.6_kernel_space_rules.mk ++++ b/quickassist/build_system/build_files/OS/linux_2.6_kernel_space_rules.mk +@@ -73,15 +73,15 @@ endif + $(LIB_STATIC): dirs + @echo 'Creating static library ${LIB_STATIC}'; \ + $(MAKE) -C $(KERNEL_SOURCE_ROOT)/ M=$(PWD) obj-m=""; \ +- echo 'Copying outputs';\ ++ echo 'Copying outputs $(OBJ)';\ ++ test -f lib.a && (ar -t lib.a | xargs ar -rcsD $($(PROG_ACY)_FINAL_OUTPUT_DIR)/$(LIB_STATIC)); \ + mv -f $(OBJ) $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ + test -f built-in.o && mv -f built-in.o $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ +- test -f lib.a && mv lib.a $($(PROG_ACY)_FINAL_OUTPUT_DIR)/$(LIB_STATIC);\ ++ test -f $($(PROG_ACY)_FINAL_OUTPUT_DIR)/lib.a && mv $($(PROG_ACY)_FINAL_OUTPUT_DIR)/lib.a $($(PROG_ACY)_FINAL_OUTPUT_DIR)/$(LIB_STATIC);\ + test -f $(OUTPUT_NAME).ko && mv -f $(OUTPUT_NAME).ko $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ + test -f $(OUTPUT_NAME).o && mv -f $(OUTPUT_NAME).o $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ + $(RM) -rf *.mod.* .*.cmd; + +- + $(MODULENAME): dirs + @echo 'Creating kernel module'; \ + $(MAKE) -C $(KERNEL_SOURCE_ROOT)/ M=$(PWD); \ +--- a/quickassist/lookaside/access_layer/src/sample_code/fips/cpa_fips_sample.h ++++ b/quickassist/lookaside/access_layer/src/sample_code/fips/cpa_fips_sample.h +@@ -109,7 +109,7 @@ extern "C" + #include + #include + #include +-#include ++#include + #else /*KERNEL_SPACE*/ + #include + #include +--- a/quickassist/lookaside/access_layer/src/sample_code/performance/qae/linux/kernel_space/qae_mem_drv.c ++++ b/quickassist/lookaside/access_layer/src/sample_code/performance/qae/linux/kernel_space/qae_mem_drv.c +@@ -85,7 +85,7 @@ + #include + + +-#include ++#include + #include + #include + +--- a/quickassist/utilities/downloader/Target_CoreLibs/halAe/icp_firml_interface.c ++++ b/quickassist/utilities/downloader/Target_CoreLibs/halAe/icp_firml_interface.c +@@ -185,7 +185,7 @@ icp_FirmLoader_MapMofAddr(void *handle, + int status = ICP_FIRMLOADER_SUCCESS; + + myHandle = (icp_firml_handle_t *)handle; +- ++ + status = UcLo_MapMofAddr(myHandle, filePtr, fileSize, + uofName, (char **)uofPtr, uofSize); + +--- a/quickassist/utilities/downloader/Target_CoreLibs/uclo/uclo_mof.c ++++ b/quickassist/utilities/downloader/Target_CoreLibs/uclo/uclo_mof.c +@@ -582,6 +582,7 @@ UcLo_MapMofAddr (icp_firml_handle_t *han + /* UOF_FID (0xc6c2) for uof object + * SUOF_FID for suof object + */ ++ + if ((((uof_fileHdr_T *) mofPtr)->fileId == UOF_FID) || + (((suof_fileHdr_T *) mofPtr)->fileId == SUOF_FID)) + { +@@ -599,7 +600,6 @@ UcLo_MapMofAddr (icp_firml_handle_t *han + /* return BADOBJ if neither UOF/SUOF nor MOF */ + else if (((mof_fileHdr_T *)mofPtr)->fileId != MOF_FID) + { +- PRINTF("unsupported file format\n"); + return (UCLO_BADOBJ); + } + +--- a/quickassist/utilities/osal/src/linux/kernel_space/OsalUsrKrlProxy.c ++++ b/quickassist/utilities/osal/src/linux/kernel_space/OsalUsrKrlProxy.c +@@ -45,7 +45,7 @@ + #include + #include + +-#include ++#include + #include + #include + +--- a/quickassist/utilities/osal/src/linux/user_space/OsalCryptoInterface.c ++++ b/quickassist/utilities/osal/src/linux/user_space/OsalCryptoInterface.c +@@ -78,7 +78,7 @@ OSAL_STATUS + osalHashSHA1(UINT8 *in, UINT8 *out) + { + SHA_CTX ctx; +- if(!SHA_Init(&ctx)) ++ if(!SHA1_Init(&ctx)) + { + return OSAL_FAIL; + } diff --git a/package/qat/firmware/quickassist-c2xxx/patches/0002-contig-mem-driver-backport.patch b/package/qat/firmware/quickassist-c2xxx/patches/0002-contig-mem-driver-backport.patch new file mode 100644 index 000000000..a312ded4c --- /dev/null +++ b/package/qat/firmware/quickassist-c2xxx/patches/0002-contig-mem-driver-backport.patch @@ -0,0 +1,5908 @@ +--- a/quickassist/Makefile ++++ b/quickassist/Makefile +@@ -80,8 +80,11 @@ else + endif + + #Paths to Top-Level Makefiles for each team#### ++KBUILD_EXTRA_SYMBOLS += $(ICP_ROOT)/quickassist/utilities/libusdm_drv/Module.symvers ++export KBUILD_EXTRA_SYMBOLS + + OSAL_PATH=$(ICP_ROOT)/quickassist/utilities/osal/ ++CMN_MEM_PATH=$(ICP_ROOT)/quickassist/utilities/libusdm_drv/ + HAL_PATH=$(ICP_ROOT)/quickassist/utilities/downloader/ + HAL_LIB_PATH=$(ICP_ROOT)/quickassist/utilities/downloader/ + QAT_FW_PATH=$(ICP_ROOT)/quickassist/lookaside/firmware/ +@@ -121,6 +124,22 @@ install_scripts: + @cp $(CONFIG_PATH)/dh89xxcc_qa_dev0_single_accel.conf $(ICP_BUILD_OUTPUT)/; + @cp $(CONFIG_PATH)/c2xxx_qa_dev0.conf $(ICP_BUILD_OUTPUT)/; + ++# ++# Common memory driver ++# ++ ++#userspace common memory library ++cmn_user: clean output_dir lac_lib_dir ++ @echo ; echo 'Building common mem driver for user space'; ++ @cd $(CMN_MEM_PATH) && $(MAKE) ARCH=$(ICP_ARCH_USER) ICP_ENV_DIR=$(ICP_TOP_ENV) OS=linux ICP_OS?=linux_2.6 ICP_OS_LEVEL=user_space CPM_UPSTREAM=1 cm_user;\ ++ echo ; echo 'Copying Common mem library'; ++ cp $(CMN_MEM_PATH)/libusdm_drv_s.so $(CMN_MEM_PATH)/libusdm_drv.a $(ICP_BUILD_OUTPUT)/; ++ ++#common mem driver ko ++cmn_ko: clean output_dir ++ @echo ; echo 'Building usdm_drv.ko'; ++ @cd $(CMN_MEM_PATH) && $(MAKE) ICP_ENV_DIR=$(ICP_TOP_ENV) OS=linux ICP_OS?=linux_2.6 ICP_OS_LEVEL=kernel_space ICP_QDM_IOMMU=1 CPM_UPSTREAM=1 cm_kernel ++ @cp $(CMN_MEM_PATH)/usdm_drv.ko $(ICP_BUILD_OUTPUT) + + #libosal needed by hal and adf + libosal: output_dir lac_lib_dir +@@ -151,7 +170,7 @@ hal_ci: output_dir libosal_ci + @echo ; echo 'Copying HAL Binary to $(LAC_LIB_DIR)'; + @cp $(HAL_LIB_PATH)/lib_linux_le/$(ICP_TOOLS_TARGET)/icp_ae_loader_kernel.a $(LAC_LIB_DIR)/ + +-adf: output_dir lac_lib_dir libosal hal ++adf: output_dir lac_lib_dir libosal hal cmn_ko + @echo ; echo 'Building ADF'; + @cd $(ADF_PATH) && export ADF_PLATFORM=ACCELDEV && export ICP_ENV_DIR=$(ICP_TOP_ENV) export ONE_KO_RELEASE_PACKAGE=1 && ICP_OS_LEVEL=kernel_space && $(MAKE); + cp $(ADF_PATH)/build/linux_2.6/libadf.a $(LAC_LIB_DIR)/; +@@ -179,7 +198,7 @@ adfvf: output_dir lac_lib_dir libosalvf + @cd $(ADF_PATH) && export ADF_PLATFORM=ACCELDEVVF && export ICP_ENV_DIR=$(ICP_TOP_ENV) export ONE_KO_RELEASE_PACKAGE=1 && ICP_OS_LEVEL=kernel_space && $(MAKE); + cp $(ADF_PATH)/build/linux_2.6/libadf.a $(LAC_LIB_DIR)/; + +-adf_user: output_dir lac_lib_dir libosal_user ++adf_user: output_dir lac_lib_dir libosal_user cmn_user + @echo ; echo 'Building user ADF'; + @cd $(ADF_PATH) && export ADF_PLATFORM=ACCELDEV && export ICP_ENV_DIR=$(ICP_TOP_ENV) && export ONE_KO_RELEASE_PACKAGE=1 && ICP_OS_LEVEL=user_space && $(MAKE) ARCH=$(ICP_ARCH_USER) adf_user; + cp $(ADF_PATH)/build/linux_2.6/libadf_proxy.a $(ICP_BUILD_OUTPUT)/; +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/Makefile +@@ -0,0 +1,142 @@ ++######################################################################### ++# ++# @par ++# This file is provided under a dual BSD/GPLv2 license. When using or ++# redistributing this file, you may do so under either license. ++# ++# GPL LICENSE SUMMARY ++# ++# Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of version 2 of the GNU General Public License as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++# The full GNU General Public License is included in this distribution ++# in the file called LICENSE.GPL. ++# ++# Contact Information: ++# Intel Corporation ++# ++# BSD LICENSE ++# ++# Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++# All rights reserved. ++# ++# Redistribution and use in source and binary forms, with or without ++# modification, are permitted provided that the following conditions ++# are met: ++# ++# * Redistributions of source code must retain the above copyright ++# notice, this list of conditions and the following disclaimer. ++# * Redistributions in binary form must reproduce the above copyright ++# notice, this list of conditions and the following disclaimer in ++# the documentation and/or other materials provided with the ++# distribution. ++# * Neither the name of Intel Corporation nor the names of its ++# contributors may be used to endorse or promote products derived ++# from this software without specific prior written permission. ++# ++# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++# ++# ++# version: QAT1.7.L.4.7.0-00006 ++############################################################################ ++ ++ ++####################Common variables and definitions######################## ++export BASE_NAME = usdm_drv ++export OSTYPE=$(shell uname -s) ++ ++ifeq ($(OSTYPE),FreeBSD) ++ICP_OS := freebsd ++OS := freebsd ++export MAKE := make ++DMESG := dmesg -c ++FBSD_VERSION := $(shell uname -r | cut -d'-' -f1,2) ++ifeq ($(FBSD_VERSION),8.4-RELEASE) ++DMESG := dmesg && sudo sysctl kern.msgbuf_clear=1 ++endif ++else ++ICP_OS?=linux_2.6 ++OS?=linux ++ICP_OS_LEVEL?=user_space ++DMESG := dmesg -C ++endif ++ ++ ++all: cm_user cm_kernel ++ @echo ; echo "Build Completed"; ++cm_user: ++ifneq ($(OSTYPE),FreeBSD) ++ @cd $(OS) && \ ++ $(MAKE) clean ICP_OS_LEVEL=user_space; ++ @cd $(OS) && \ ++ $(MAKE) ICP_OS_LEVEL=user_space lib_shared UT=$(UT) BE=$(BE); ++ @cd $(OS) && \ ++ $(MAKE) ICP_OS_LEVEL=user_space lib_static UT=$(UT) BE=$(BE); ++ @cp $(OS)/build/$(ICP_OS)/user_space/lib$(BASE_NAME)_s.so lib$(BASE_NAME)_s.so ; ++ @cp $(OS)/build/$(ICP_OS)/user_space/lib$(BASE_NAME).a lib$(BASE_NAME).a ; ++else ++ @cd $(ICP_OS) && \ ++ make clean ICP_OS_LEVEL=user_space; ++ @cd $(ICP_OS) && \ ++ make ICP_OS_LEVEL=user_space; ++ @cp $(ICP_OS)/user_space/libusdm_drv.so.0 libusdm_drv_s.so ; ++ @cp $(ICP_OS)/user_space/libusdm_drv.a libusdm_drv.a ; ++endif ++ ++cm_kernel: ++ifneq ($(OSTYPE),FreeBSD) ++ @echo $(ICP_BUILDSYSTEM_PATH) ++ @cd $(OS) && \ ++ $(MAKE) clean ICP_OS_LEVEL=kernel_space && \ ++ $(MAKE) ICP_OS_LEVEL=kernel_space UT=$(UT) BE=$(BE); ++ @mv $(OS)/build/$(ICP_OS)/kernel_space/$(BASE_NAME).a $(OS)/build/$(ICP_OS)/kernel_space/lib$(BASE_NAME).a ; ++ @cp linux/Module.symvers Module.symvers; ++ @cp $(OS)/build/$(ICP_OS)/kernel_space/$(BASE_NAME).ko $(BASE_NAME).ko; ++else ++ @cd $(ICP_OS) && \ ++ make clean ICP_OS_LEVEL=kernel_space && \ ++ make ICP_OS_LEVEL=kernel_space UT=$(UT); ++ @cp $(ICP_OS)/kernel_space/usdm_drv.ko usdm_drv.ko; ++endif ++ ++bsd_kernel: ++ @cd $(ICP_OS) && \ ++ make clean ICP_OS_LEVEL=kernel_space && \ ++ make ICP_OS_LEVEL=kernel_space UT=$(UT); ++ @cp $(ICP_OS)/kernel_space/$(BASE_NAME).ko $(BASE_NAME).ko; ++ ++ ++clean: ++ rm -f *.a *.so *.ko ++ @cd $(OS) && \ ++ rm -f kernel_space/.*.cmd && \ ++ rm -f kernel_space/.depend* && \ ++ rm -f user_space/.depend* && \ ++ $(MAKE) ICP_OS_LEVEL=user_space clean && \ ++ $(MAKE) ICP_OS_LEVEL=kernel_space clean ++ ++doxygen: ++ @doxygen qae_mem.h > doxygen_output.txt 2>&1; ++ @echo "The doxygen file is available at $(PWD)/html/index.html" ++ @echo "The doxygen command output is available at $(PWD)/doxygen_output.txt" +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/Makefile +@@ -0,0 +1,197 @@ ++######################################################################### ++# ++# @par ++# This file is provided under a dual BSD/GPLv2 license. When using or ++# redistributing this file, you may do so under either license. ++# ++# GPL LICENSE SUMMARY ++# ++# Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of version 2 of the GNU General Public License as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++# The full GNU General Public License is included in this distribution ++# in the file called LICENSE.GPL. ++# ++# Contact Information: ++# Intel Corporation ++# ++# BSD LICENSE ++# ++# Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++# All rights reserved. ++# ++# Redistribution and use in source and binary forms, with or without ++# modification, are permitted provided that the following conditions ++# are met: ++# ++# * Redistributions of source code must retain the above copyright ++# notice, this list of conditions and the following disclaimer. ++# * Redistributions in binary form must reproduce the above copyright ++# notice, this list of conditions and the following disclaimer in ++# the documentation and/or other materials provided with the ++# distribution. ++# * Neither the name of Intel Corporation nor the names of its ++# contributors may be used to endorse or promote products derived ++# from this software without specific prior written permission. ++# ++# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++# ++# ++# version: QAT1.7.L.4.7.0-00006 ++############################################################################ ++ ++ ++####################Common variables and definitions######################## ++ICP_OS?=linux_2.6 ++OS?=linux ++ICP_OS_LEVEL?=user_space ++CMN_ROOT?=$(ICP_ROOT)/quickassist/utilities/libusdm_drv ++QAT_DRV?=$(ICP_ROOT)/quickassist/qat ++ ++#include the makefile with all the default and common Make variable definitions ++include $(ICP_BUILDSYSTEM_PATH)/build_files/common.mk ++ ++# List of Source Files to be compiled (to be in a single line or on different lines separated by a "\" and tab. ++ ++ifeq ($(ICP_OS_LEVEL),user_space) ++SOURCES:= $(ICP_OS_LEVEL)/qae_mem_utils.c $(ICP_OS_LEVEL)/qae_mem_hugepage_utils.c ++else ++MODULE_SOURCES:= $(ICP_OS_LEVEL)/qae_mem_drv.c ++SOURCES:=$(ICP_OS_LEVEL)/qae_mem_utils.c ++endif ++ ++ifeq ($(UT),1) ++MODULE_SOURCES+= ../test/$(OS)/$(ICP_OS_LEVEL)/qae_mem_drv_utils.c $(ICP_OS_LEVEL)/qdm.c ++else ++MODULE_SOURCES+= $(ICP_OS_LEVEL)/qae_mem_drv_utils.c $(ICP_OS_LEVEL)/qdm.c ++endif ++ ++INCLUDES += -I$(CMN_ROOT) ++ ++INCLUDES += -I$(CMN_ROOT)/$(OS)/include ++ ++ifeq ($(ICP_ADF_IOMMU), 1) ++EXTRA_CFLAGS += -DICP_ADF_IOMMU ++KBUILD_EXTRA_SYMBOLS+=$(QAT_DRV)/src/Module.symvers ++export KBUILD_EXTRA_SYMBOLS ++endif ++ ++ifeq ($(ICP_OSAL_IOMMU), 1) ++EXTRA_CFLAGS += -DICP_OSAL_IOMMU ++KBUILD_EXTRA_SYMBOLS+=$(QAT_DRV)/src/Module.symvers ++export KBUILD_EXTRA_SYMBOLS ++endif ++ ++ifeq ($(ICP_QDM_IOMMU), 1) ++EXTRA_CFLAGS += -DICP_QDM_IOMMU ++KBUILD_EXTRA_SYMBOLS+=$(QAT_DRV)/Module.symvers ++export KBUILD_EXTRA_SYMBOLS ++endif ++ ++ifdef QAE_USE_128K_SLABS ++EXTRA_CFLAGS+=-DQAE_NUM_PAGES_PER_ALLOC=32 ++endif ++ ++ifeq ($(ICP_OS_LEVEL),user_space) ++EXTRA_CFLAGS += -DUSER_SPACE ++EXTRA_CFLAGS += -Wextra -Werror -Wno-missing-field-initializers ++ifdef ICP_X86 ++EXTRA_CFLAGS += -m32 -D_FILE_OFFSET_BITS=64 ++LIB_SHARED_FLAGS += -m elf_i386 ++endif ++ifdef ICP_DISABLE_SECURE_MEM_FREE ++EXTRA_CFLAGS += -DICP_DISABLE_SECURE_MEM_FREE ++endif ++ifdef ICP_WITHOUT_THREAD ++EXTRA_CFLAGS += -DICP_WITHOUT_THREAD ++endif ++else ++ ++EXTRA_CFLAGS += -DKERNEL_SPACE ++ifeq ($(BE) ,1) ++KBUILD_EXTRA_SYMBOLS+=$(BE_DIR)/run/linuxKernel/Module.symvers ++export KBUILD_EXTRA_SYMBOLS ++endif ++ifdef ICP_NO_PROC_SUPPORT ++EXTRA_CFLAGS += -DICP_NO_PROC_SUPPORT ++endif ++ ++# Check for defense with stack protection in kernel ++ifeq ($(KERNEL_DEFENSES_STACK_PROTECTION), n) ++STACK_PROTECTION=-fstack-protector -fstack-protector-strong ++EXTRA_CFLAGS := $(filter-out $(STACK_PROTECTION), $(EXTRA_CFLAGS)) ++endif ++endif ++ ++ifeq ($(ICP_OS_LEVEL),user_space) ++#include os dependent rules ++include $(ICP_ENV_DIR)/$(ICP_OS)_$(ICP_OS_LEVEL).mk ++lib: lib_shared ++all: lib_shared ++OUTPUT_NAME=lib$(BASE_NAME) ++export OUTPUT_NAME ++else ++ ++OUTPUT_NAME=$(BASE_NAME) ++export OUTPUT_NAME ++ ++#kernel space rules here ++#produce two artefacts: module and static library and copy them ++ifeq ($(OS),linux) ++EXTRA_CFLAGS+=-I$(INCLUDES) -Werror -ftree-ter ++obj-m+=$(OUTPUT_NAME).o ++$(OUTPUT_NAME)-objs :=$(patsubst %.c,%.o, $(MODULE_SOURCES)) $(ADDITIONAL_KERNEL_LIBS) ++lib-m := $(patsubst %.c,%.o, $(SOURCES)) $(patsubst %.S,%.o, $(ASM_SOURCES)) ++$(LIB_STATIC): dirs ++ @echo 'Creating static library ${LIB_STATIC}'; \ ++ $(MAKE) -C $(KERNEL_SOURCE_ROOT)/ M=$(PWD) obj-m=""; \ ++ echo 'Copying outputs';\ ++ mv -f $(OBJ) $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ ++ test -f built-in.o && mv -f built-in.o $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ ++ test -f lib.a && mv lib.a $($(PROG_ACY)_FINAL_OUTPUT_DIR)/$(LIB_STATIC);\ ++ test -f $(OUTPUT_NAME).ko && mv -f $(OUTPUT_NAME).ko $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ ++ test -f $(OUTPUT_NAME).o && mv -f $(OUTPUT_NAME).o $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ ++ $(RM) -rf *.mod.* .*.cmd; ++ ++$(MODULENAME): dirs ++ @echo 'Creating kernel module'; \ ++ $(MAKE) -C $(KERNEL_SOURCE_ROOT)/ M=$(PWD); \ ++ echo 'Copying outputs';\ ++ mv -f $(OBJ) $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ ++ test -f built-in.o && mv -f built-in.o $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ ++ test -f lib.a && mv lib.a $($(PROG_ACY)_FINAL_OUTPUT_DIR)/$(LIB_STATIC);\ ++ test -f $(OUTPUT_NAME).ko && mv -f $(OUTPUT_NAME).ko $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ ++ test -f $(OUTPUT_NAME).o && mv -f $(OUTPUT_NAME).o $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ ++ $(RM) -rf *.mod.* .*.cmd; ++else ++include $(ICP_ENV_DIR)/$(ICP_OS)_$(ICP_OS_LEVEL).mk ++endif ++ ++all: module ++install: module ++endif ++###################Include rules makefiles######################## ++include $(ICP_BUILDSYSTEM_PATH)/build_files/rules.mk ++ ++###################End of Rules inclusion######################### +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/include/qae_mem_utils.h +@@ -0,0 +1,757 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++/** ++***************************************************************************** ++* @file qae_mem_utils.h ++* ++* This file provides linux kernel memory allocation for quick assist API ++* ++*****************************************************************************/ ++#ifndef QAE_MEM_UTILS_H_ ++#define QAE_MEM_UTILS_H_ ++#if defined(__KERNEL__) ++#ifdef __FreeBSD__ ++#include ++#include ++#include ++#include ++MALLOC_DECLARE(M_QAE_MEM); ++#else ++#include ++#include ++#include ++ ++#if (KERNEL_VERSION(2, 6, 38) >= LINUX_VERSION_CODE) ++#define kstrtoll strict_strtoll ++#endif /* KERNEL_VERSION */ ++#endif /* OS selection */ ++#endif /* __KERNEL__ */ ++ ++#define USDM_MOD "usdm_drv: " ++ ++#define mm_err(...) pr_err(USDM_MOD __VA_ARGS__) ++ ++#define mm_info(...) pr_info(USDM_MOD __VA_ARGS__) ++ ++#define mm_warning(...) pr_warning(USDM_MOD __VA_ARGS__) ++ ++/*define types which need to vary between 32 and 64 bit*/ ++#define QAE_PAGE_SHIFT 12 ++#define QAE_PAGE_SIZE (1UL << QAE_PAGE_SHIFT) ++ ++/* QAE_NUM_PAGES_PER_ALLOC can be defined as 32 pages when library ++is built, default is 512 */ ++#ifndef QAE_NUM_PAGES_PER_ALLOC ++#define QAE_NUM_PAGES_PER_ALLOC 512 ++#endif ++ ++#define STATIC static ++ ++#define QAE_PHYS_ADDR uint64_t ++ ++#define QAE_MEM_ZALLOC_GEN(size) kzalloc(size, GFP_KERNEL) ++#define QAE_MEM_FREE(ptr) \ ++ do \ ++ { \ ++ if (ptr) \ ++ { \ ++ kfree(ptr); \ ++ ptr = NULL; \ ++ } \ ++ } while (0) ++/** ++ ***************************************************************************** ++ * @ingroup perfCodeFramework ++ * Framework aligned memory structure. ++ * @description ++ * This structure is used to assist the framework in allocating aligned ++ * memory ++ ****************************************************************************/ ++typedef struct qae_mem_alloc_info_s ++{ ++ void *mAllocMemPtr; /* memory addr returned by the kernel */ ++ size_t mSize; /* allocated size */ ++ ++} qae_mem_alloc_info_t; ++ ++enum slabType ++{ ++ SMALL = 0, ++ LARGE = 1, ++ HUGE_PAGE = 2, ++}; ++ ++/* User space memory information structure. */ ++typedef struct dev_mem_info_s ++{ ++ int64_t nodeId; /* shared b/w user/kernel */ ++ /* Node id for NUMA */ ++ uint64_t size; /* shared b/w user/kernel */ ++ /* Size of this block (bytes) */ ++ enum slabType type; ++ /* Slab for normal memory or large memory */ ++ uint32_t allocations; /* user space only */ ++ /* Huge page file descriptor */ ++ int64_t hpg_fd; /* user space only */ ++ /* The huge page file descriptor of each slab */ ++ uint64_t phy_addr; /* shared b/w user/kernel */ ++ /* Physical address of the kmalloced area */ ++ union { ++ void *virt_addr; /* user space only */ ++ uint64_t padding_virt; ++ }; ++ /* Base address in user space - i.e. virtual address */ ++ union { ++ struct dev_mem_info_s *pPrev_user; /* user space only */ ++ uint64_t padding_prevu; ++ }; ++ union { ++ struct dev_mem_info_s *pNext_user; /* user space only */ ++ uint64_t padding_nextu; ++ }; ++ union { ++ struct dev_mem_info_s *pPrev_user_hash; /* user space only */ ++ uint64_t padding_prevuh; ++ }; ++ union { ++ struct dev_mem_info_s *pNext_user_hash; /* user space only */ ++ uint64_t padding_nextuh; ++ }; ++} dev_mem_info_t; ++ ++/* Kernel space memory information structure. */ ++typedef struct kdev_mem_info_s ++{ ++ void *kmalloc_ptr; /* kernel space only (small slab) */ ++ /* Pointer to mem originally returned by kmalloc */ ++ void *huge_mem_ctrl; ++ uint64_t size; ++ /* Slab size */ ++ uint64_t phy_addr; /* shared b/w user/kernel */ ++ /* Physical address of the kmalloc'ed area */ ++ struct kdev_mem_info_s *pPrev_kernel; ++ struct kdev_mem_info_s *pNext_kernel; ++ struct kdev_mem_info_s *pPrev_kernel_hash; ++ struct kdev_mem_info_s *pNext_kernel_hash; ++} kdev_mem_info_t; ++ ++typedef struct user_page_info_s ++{ ++ /* Use 64-bit unsigned to support 32bit application on ++ * a 64-bit kernel */ ++ uint64_t virt_addr; ++ /* physical address shared b/w user/kernel */ ++ uint64_t phy_addr; ++} user_page_info_t; ++ ++/* size of allocation unit */ ++#define UNIT_SIZE 1024 ++#define QAE_KBYTE 1024 ++#define QWORD_WIDTH (8 * sizeof(uint64_t)) ++#define QWORD_ALL_ONE 0xFFFFFFFFFFFFFFFFULL ++ ++/* ++Bitmap is used to keep track the allocation of each block ++Each 1k block is represented by one bit allocated(1)/free(0) ++BITMAP_LEN is a macro the represents the number of 64-bit quad words ++that make up the bitmap ++with 512 pages of 4k page and 1k units this value is 32 ++ */ ++#define CHUNK_SIZE (UNIT_SIZE * QWORD_WIDTH) ++ ++#define BITMAP_LEN (QAE_NUM_PAGES_PER_ALLOC * QAE_PAGE_SIZE / CHUNK_SIZE) ++ ++#define BLOCK_SIZES (BITMAP_LEN * QWORD_WIDTH) ++ ++/*block control structure */ ++typedef struct block_ctrl_s ++{ ++ dev_mem_info_t mem_info; /* memory device info type */ ++ /* adding an extra element at the end to make a barrier */ ++ uint64_t bitmap[BITMAP_LEN + 1]; /* bitmap each bit represents a 1k block */ ++ uint16_t sizes[BLOCK_SIZES]; /* Holds the size of each allocated block */ ++} block_ctrl_t; ++ ++/** ++ ***************************************************************************** ++ * @ingroup qaeMemUtils ++ * array structure ++ * @description ++ * This structure is used to copy chunks of data read from files ++ * from user to kernel space ++ ****************************************************************************/ ++typedef struct dev_mem_file_s ++{ ++ unsigned char data[2048]; ++ unsigned int size; ++} dev_mem_file_t; ++ ++/** ++ ***************************************************************************** ++ * @ingroup qaeMemUtils ++ * user space memory list pointer structure. ++ * @description ++ * This structure is used to assist in allocating aligned ++ * memory ++ ****************************************************************************/ ++typedef struct user_proc_mem_list_s ++{ ++ int pid; ++ uint64_t allocs_nr; ++ uint64_t hugepages_nr; ++ kdev_mem_info_t *head; ++ kdev_mem_info_t *tail; ++ struct user_proc_mem_list_s *pPrev; ++ struct user_proc_mem_list_s *pNext; ++} user_proc_mem_list_t; ++/** ++ ***************************************************************************** ++ * @ingroup qaeMemUtils ++ * user space memory list pointer structure. ++ * @description ++ * This structure is used to assist in allocating aligned ++ * memory ++ ****************************************************************************/ ++typedef struct user_mem_dev_s ++{ ++ user_proc_mem_list_t *head; ++ user_proc_mem_list_t *tail; ++} user_mem_dev_t; ++ ++/* ++ ****************************************************************************** ++ * @ingroup ADD_ELEMENT_TO_HEAD_LIST ++ * insert element at the head of a linked list ++ * @description ++ * inserts a new element at the head of a ++ * double linked list in user or kernel mode ++ * depending on mode parameter if mode is an ++ * empty string kernel mode is used ++ * elementToAdd - ptr to the new element ++ * headPtr - ptr to the first element in list ++ * tailPtr - ptr to the last element int the list ++ * mode - _kernel,_user or empty ++ ******************************************************************************/ ++ ++#define ADD_ELEMENT_TO_HEAD_LIST(elementToAdd, headPtr, tailPtr, mode) \ ++ do \ ++ { \ ++ elementToAdd->pPrev##mode = NULL; \ ++ if (NULL == headPtr) \ ++ { \ ++ tailPtr = elementToAdd; \ ++ elementToAdd->pNext##mode = NULL; \ ++ } \ ++ else \ ++ { \ ++ elementToAdd->pNext##mode = headPtr; \ ++ headPtr->pPrev##mode = elementToAdd; \ ++ } \ ++ headPtr = elementToAdd; \ ++ } while (0) ++ ++/* ++ ****************************************************************************** ++ * @ingroup ADD_ELEMENT_TO_END_LIST ++ * insert element at the end of a linked list ++ * @description ++ * inserts a new element at the head of a ++ * double linked list in user or kernel mode ++ * depending on mode parameter if mode is an ++ * empty string kernel mode is used ++ * elementToAdd - ptr to the new element ++ * headPtr - ptr to the first element in list ++ * tailPtr - ptr to the last element int the list ++ * mode - _kernel,_user or empty ++ ******************************************************************************/ ++ ++#define ADD_ELEMENT_TO_END_LIST(elementToAdd, headPtr, tailPtr, mode) \ ++ do \ ++ { \ ++ elementToAdd->pNext##mode = NULL; \ ++ if (NULL == tailPtr) \ ++ { \ ++ headPtr = elementToAdd; \ ++ elementToAdd->pPrev##mode = NULL; \ ++ } \ ++ else \ ++ { \ ++ elementToAdd->pPrev##mode = tailPtr; \ ++ tailPtr->pNext##mode = elementToAdd; \ ++ } \ ++ tailPtr = elementToAdd; \ ++ } while (0) ++ ++/* ++ ****************************************************************************** ++ * @ingroup REMOVE_ELEMENT_FROM_LIST ++ * remove element at the end of a linked list ++ * @description ++ * removes an element from a ++ * double linked list in user or kernel mode ++ * depending on mode parameter if mode is an ++ * empty string kernel mode is used ++ * elementToREmove - ptr to the new element ++ * headPtr - ptr to the first element in list ++ * tailPtr - ptr to the last element int the list ++ * mode - _kernel,_user or empty ++ ******************************************************************************/ ++ ++#define REMOVE_ELEMENT_FROM_LIST(elementToRemove, headPtr, tailPtr, mode) \ ++ do \ ++ { \ ++ if (NULL != elementToRemove->pPrev##mode) \ ++ { \ ++ elementToRemove->pPrev##mode->pNext##mode = \ ++ elementToRemove->pNext##mode; \ ++ if (NULL != elementToRemove->pNext##mode) \ ++ { \ ++ elementToRemove->pNext##mode->pPrev##mode = \ ++ elementToRemove->pPrev##mode; \ ++ } \ ++ else \ ++ { \ ++ tailPtr = elementToRemove->pPrev##mode; \ ++ } \ ++ } \ ++ else \ ++ { \ ++ if (NULL != elementToRemove->pNext##mode) \ ++ { \ ++ elementToRemove->pNext##mode->pPrev##mode = NULL; \ ++ headPtr = elementToRemove->pNext##mode; \ ++ } \ ++ else \ ++ { \ ++ headPtr = NULL; \ ++ tailPtr = NULL; \ ++ } \ ++ } \ ++ } while (0) ++ ++/* IOCTL number for use between the kernel and the user space application */ ++#define DEV_MEM_MAGIC 'q' ++#define DEV_MEM_CMD_MEMALLOC (0) ++#define DEV_MEM_CMD_MEMFREE (1) ++#define DEV_MEM_CMD_RELEASE (2) ++#define DEV_MEM_CMD_UNREGISTER (3) ++#define DEV_MEM_CMD_GET_NUM_HPT (4) ++#define DEV_MEM_CMD_GET_USER_PAGE (5) ++ ++/* IOCTL commands for requesting kernel memory */ ++#define DEV_MEM_IOC_MEMALLOC \ ++ _IOWR(DEV_MEM_MAGIC, DEV_MEM_CMD_MEMALLOC, dev_mem_info_t) ++ ++#define DEV_MEM_IOC_MEMFREE \ ++ _IOWR(DEV_MEM_MAGIC, DEV_MEM_CMD_MEMFREE, dev_mem_info_t) ++ ++#define DEV_MEM_IOC_RELEASE _IO(DEV_MEM_MAGIC, DEV_MEM_CMD_RELEASE) ++ ++#define DEV_MEM_IOC_UNREGISTER \ ++ _IOWR(DEV_MEM_MAGIC, DEV_MEM_CMD_UNREGISTER, dev_mem_info_t) ++ ++#define DEV_MEM_IOC_GET_NUM_HPT \ ++ _IOWR(DEV_MEM_MAGIC, DEV_MEM_CMD_GET_NUM_HPT, uint32_t) ++ ++#define DEV_MEM_IOC_GET_USER_PAGE \ ++ _IOWR(DEV_MEM_MAGIC, DEV_MEM_CMD_GET_USER_PAGE, user_page_info_t) ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeMemInit ++ * ++ * @description ++ * Initialize the user-space allocator, opening the device driver ++ * used to communicate with the kernel-space. ++ * ++ * @param[in] path - path to the specific device ++ * ++ * @retval 0 if the open of the device was successful and ++ * non-zero otherwise ++ * @pre ++ * none ++ * @post ++ * Allocator is initialized ++ * ++ ****************************************************************************/ ++int32_t qaeMemInit(void); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeMemDestroy ++ * ++ * @description ++ * Release the user-space allocator. It closes the file descriptor ++ * associated with the device driver ++ * ++ * @param[in] none ++ * ++ * @retval none ++ * ++ * @pre ++ * The user space allocator is initialized using qaeMemInit ++ * @post ++ * The user-space allocator is released ++ * ++ ****************************************************************************/ ++void qaeMemDestroy(void); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeIOMMUInit ++ * ++ * @description ++ * Function creates iommu domain. Applicable when IOMMU is enabled ++ * ++ * @param[in] none ++ * ++ * @retval 0 - if successful. ++ * non-zero - otherwise ++ * ++ * @pre ++ * IOMMU is enabled. ++ * @post ++ * iommu domain created ++ * ++ ****************************************************************************/ ++int32_t qaeIOMMUInit(void); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeIOMMUExit ++ * ++ * @description ++ * Function removes iommu domain. Applicable when IOMMU is enabled ++ * ++ * @param[in] none ++ * ++ * @retval none ++ * ++ * @pre ++ * IOMMU is enabled and an iommu domain is created using qaeIOMMUInit ++ * @post ++ * iommu domain removed ++ * ++ ****************************************************************************/ ++void qaeIOMMUExit(void); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeIOMMUgetRemappingSize ++ * ++ * @description ++ * Function calculates size for remapping when IOMMU is enabled. ++ * Before calling any of the qaeMemAlloc functions, this function can be ++ * used to calculate the actual size of memory to be allocated. ++ * The remapping size is at least PAGE_SIZE. ++ * ++ * @param[in] size - Actual size of the memory to be allocated ++ * ++ * @retval Remapping size ++ * ++ * @pre ++ * IOMMU is enabled and an iommu domain is created using qaeIOMMUInit. ++ * @post ++ * Remapping size provided. ++ * ++ ****************************************************************************/ ++size_t qaeIOMMUgetRemappingSize(size_t size); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeIOMMUMap ++ * ++ * @description ++ * Function adds mapping from io virtual address to a physical address. ++ * Applicable when IOMMU is enabled ++ * ++ * @param[in] phaddr - Host physical address. ++ * @param[in] iova - IO virtual address. ++ * @param[in] size - Memory size to be remapped obtained from ++ * qaeIOMMUgetRemappingSize() function. ++ * ++ * @retval CPA_STATUS_SUCCESS - if successful. ++ * CPA_STATUS_UNSUPPORTED - if not supported ++ * CPA_STATUS_FAIL - otherwise ++ * ++ * @pre ++ * An iommu domain is created using qaeIOMMUInit. iova points to ++ * previously allocated memory. phaddr is already obtained using ++ * iova using virt_to_phys or similar functions. size is calculated ++ * using qaeIOMMUgetRemappingSize function. ++ * @post ++ * IO virtual address mapped ++ ****************************************************************************/ ++int32_t qaeIOMMUMap(uint64_t phaddr, uint64_t iova, size_t size); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeIOMMUUnmap ++ * ++ * @description ++ * Function removes mapping from io virtual address to a physical ++ * address. Applicable when IOMMU is enabled ++ * ++ * @param[in] iova - IO virtual address. ++ * @param[in] size - Memory size to be unmapped ++ * ++ * @retval CPA_STATUS_SUCCESS - if successful. ++ * CPA_STATUS_UNSUPPORTED - if not supported ++ * CPA_STATUS_FAIL - otherwise ++ * ++ * @pre ++ * An iommu domain is created using qaeIOMMUInit. iova points to ++ * previously allocated memory. ++ * @post ++ * IO virtual address unmapped ++ ****************************************************************************/ ++int32_t qaeIOMMUUnmap(uint64_t iova, size_t size); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeIOMMUVirtToPhys ++ * ++ * @description ++ * Function translates io virtual address to a physical address. ++ * Applicable when IOMMU is enabled. ++ * ++ * @param[in] iova, IO virtual address ++ * ++ * @retval host physical address - if successful ++ * NULL Otherwise ++ * ++ * @pre ++ * An iommu domain is created using qaeIOMMUInit. iova points to ++ * previously allocated memory. ++ * @post ++ * virtual address is translated to physical address ++ * ++ ****************************************************************************/ ++uint64_t qaeIOMMUVirtToPhys(uint64_t iova); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeIOMMUAttachDev ++ * ++ * @description ++ * This function attaches a pci dev (VF) to an iommu domain. ++ * Applicable when IOMMU/SRIOV are enabled and after the driver bringup ++ * in Host is succesful. ++ * ++ * @param[in] dev, Device to be attached ++ * ++ * @retval CPA_STATUS_SUCCESS - if successful ++ * CPA_STATUS_UNSUPPORTED - if not supported ++ * CPA_STATUS_FAIL - otherwise ++ * ++ * @pre ++ * An iommu domain is created using qaeIOMMUInit. Driver bringup ++ * in Host is succesful. ++ * @post ++ * device is attached ++ * ++ ****************************************************************************/ ++int32_t qaeIOMMUAttachDev(void *dev); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeIOMMUDetachDev ++ * ++ * @description ++ * Function detaches pci dev to iommu domain ++ * ++ * @param[in] dev, Device to be detached ++ * ++ * @retval none ++ * ++ * @pre ++ * An iommu domain is created using qaeIOMMUInit, Driver bringup ++ * in Host is succesful and dev is already ++ * attached using qaeIOMMUAttachDev ++ * @post ++ * Device is detached ++ * ++ ****************************************************************************/ ++void qaeIOMMUDetachDev(void *dev); ++ ++/** ++ ***************************************************************************** ++ * @ingroup CommonMemoryDriver ++ * printMemAllocations ++ * ++ * @description ++ * Prints only the overall count of NUMA and non-NUMA memory allocations ++ * performed. This doesn't provide other details like the allocation ++ * sizes, pointers etc. ++ * ++ * @retval none ++ * ++ * @pre ++ * The user space allocator is initialized using qaeMemInit ++ * @post ++ * memory allocation count printed ++ * ++ ****************************************************************************/ ++void printMemAllocations(void); ++ ++#ifndef __KERNEL__ ++#ifdef ICP_WITHOUT_THREAD ++#define mem_mutex_lock(x) (0) ++#define mem_mutex_unlock(x) (0) ++#else ++#define mem_mutex_lock(x) pthread_mutex_lock(x) ++#define mem_mutex_unlock(x) pthread_mutex_unlock(x) ++#endif ++ ++#define mem_ioctl(fd, cmd, pMemInfo) ioctl(fd, cmd, pMemInfo) ++#define qae_open(file, options) open(file, options) ++#define qae_lseek(fd, offset, whence) lseek(fd, offset, whence) ++#define qae_read(fd, buf, nbytes) read(fd, buf, nbytes) ++#define qae_mmap(addr, length, prot, flags, fd, offset) \ ++ mmap(addr, length, prot, flags, fd, offset) ++#define qae_munmap(addr, length) munmap(addr, length) ++#define qae_madvise(addr, len, advice) madvise(addr, len, advice) ++#define qae_mkstemp(template) mkstemp(template) ++#endif ++ ++#if defined(__KERNEL__) ++#if defined(ICP_ADF_IOMMU) ++int icp_adf_iommu_map(void *iova, void *phaddr, size_t size); ++int icp_adf_iommu_unmap(void *iova, size_t size); ++size_t icp_adf_iommu_get_remapping_size(size_t size); ++static inline int icp_iommu_map(void **iova, void *vaddr, size_t size) ++{ ++ void *phaddr = (void *)virt_to_phys(vaddr); ++ *iova = phaddr; ++ return icp_adf_iommu_map(*iova, phaddr, size); ++} ++static inline int icp_iommu_unmap(void *iova, size_t size) ++{ ++ return icp_adf_iommu_unmap(iova, size); ++} ++static inline size_t icp_iommu_get_remapping_size(size_t size) ++{ ++ return icp_adf_iommu_get_remapping_size(size); ++} ++#elif defined(ICP_OSAL_IOMMU) ++int osalIOMMUMap(uint64_t iova, uint64_t phaddr, size_t size); ++static inline int icp_iommu_map(void **iova, void *vaddr, size_t size) ++{ ++ void *phaddr = (void *)virt_to_phys(vaddr); ++ *iova = phaddr; ++ return osalIOMMUMap((uintptr_t)*iova, phaddr, size); ++} ++ ++int osalIOMMUUnmap(uint64_t iova, size_t size); ++static inline int icp_iommu_unmap(void *iova, size_t size) ++{ ++ return osalIOMMUUnmap((uintptr_t)iova, size); ++} ++uint64_t osalIOMMUVirtToPhys(uint64_t iova); ++static inline uint64_t icp_iommu_virt_to_phys(void *iova) ++{ ++ return osalIOMMUVirtToPhys((uintptr_t)iova); ++} ++size_t osalIOMMUgetRemappingSize(size_t size); ++static inline size_t icp_iommu_get_remapping_size(size_t size) ++{ ++ return osalIOMMUgetRemappingSize(size); ++} ++#elif defined(ICP_QDM_IOMMU) ++int qdm_iommu_map(void **iova, void *vaddr, size_t size); ++int qdm_iommu_unmap(void *iova, size_t size); ++static inline int icp_iommu_map(void **iova, void *vaddr, size_t size) ++{ ++ return qdm_iommu_map(iova, vaddr, size); ++} ++static inline int icp_iommu_unmap(void *iova, size_t size) ++{ ++ return qdm_iommu_unmap(iova, size); ++} ++static inline size_t icp_iommu_get_remapping_size(size_t size) ++{ ++ return (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); ++} ++#else ++#define ICP_IOMMU_DISABLED ++static inline int icp_iommu_map(void **iova, void *vaddr, size_t size) ++{ ++#ifdef __FreeBSD__ ++ *iova = (void *)(uintptr_t)vtophys(vaddr); ++#else ++ *iova = (void *)(uintptr_t)virt_to_phys(vaddr); ++#endif ++ return 0; ++} ++ ++static inline int icp_iommu_unmap(void *iova, size_t size) ++{ ++ return 0; ++} ++static inline size_t icp_iommu_get_remapping_size(size_t size) ++{ ++ return (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); ++} ++#endif ++#endif ++#endif +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/include/qdm.h +@@ -0,0 +1,61 @@ ++/* ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * Copyright(c) 2016 Intel Corporation. ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * Contact Information: ++ * ++ * qat-linux@intel.com ++ * ++ * BSD LICENSE ++ * Copyright(c) 2016 Intel Corporation. ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++#ifndef __QDM_H__ ++#define __QDM_H__ ++#include ++ ++struct device; ++ ++int qdm_init(void); ++void qdm_exit(void); ++int qdm_attach_device(struct device *dev); ++int qdm_detach_device(struct device *dev); ++int qdm_iommu_map(dma_addr_t *iova, void *vaddr, size_t size); ++int qdm_iommu_unmap(dma_addr_t iova, size_t size); ++ ++#endif /* __QDM_H__ */ +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/kernel_space/qae_mem_drv.c +@@ -0,0 +1,1590 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++ ++/** ++ * ++ * @file qae_mem_drv.c ++ * ++ * @brief Kernel-space support for user-space contiguous memory allocation ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "qae_mem_utils.h" ++ ++#define DEV_MEM_NAME "usdm_drv" ++#define MODULE_NAME "USDM" ++#define DEV_MEM_MAJOR 0 ++#define DEV_MEM_MAX_MINOR 1 ++#define DEV_MEM_BASE_MINOR 0 ++#define QAE_LOCAL_ENSURE(c, str, ret) \ ++ if (!(c)) { \ ++ mm_err("%s in file %s, ret = %d\n", \ ++ str, __FILE__, ret); \ ++ return ret; } ++ ++#define FREE(ptr) kfree(ptr) ++#define IS_PAGE_ALIGNED(x) (PAGE_ALIGN((uintptr_t) (x)) == (uintptr_t) (x)) ++ ++/** ++****************************************************************************** ++* @ingroup max_mem_numa ++* maximum amount of memory allocated in kernel space ++* @description ++* This is a command line parameter that defines the maximum ++* amount of memory allocated by the driver in kernel space. ++* Measured in kilobytes. ++*****************************************************************************/ ++static uint32_t max_mem_numa = 0; ++/** ++****************************************************************************** ++* @ingroup mem_allocated ++* amount of memory currently allocated in kernel space ++* @description ++* This variable holds the overall ++* amount of memory allocated by the driver in kernel space. ++* Measured in bytes. ++*****************************************************************************/ ++static size_t mem_allocated = 0; ++/** ++****************************************************************************** ++* @ingroup max_huge_pages ++* total number of huge pages currently reserved ++* @description ++* This variable holds the total number of ++* huge pages reserved by the memory driver. ++* Measured in number of huge pages. ++*****************************************************************************/ ++static uint max_huge_pages = 0; ++/** ++****************************************************************************** ++* @ingroup max_huge_pages_per_process ++* number of huge pages could be allocated ++* for each user space process ++* @description ++* This variable holds the number of ++* huge pages allocated by each process. ++* Measured in number of huge pages. ++*****************************************************************************/ ++static uint max_huge_pages_per_process = 0; ++ ++ ++module_param(max_mem_numa, uint, S_IRUGO); ++MODULE_PARM_DESC(max_mem_numa, ++ "Maximum number of allocatable memory in 1k units"); ++ ++module_param(max_huge_pages, uint, S_IRUGO); ++MODULE_PARM_DESC(max_huge_pages, ++ "Maximum number of huge pages enabled for the module"); ++ ++module_param(max_huge_pages_per_process, uint, S_IRUGO); ++MODULE_PARM_DESC(max_huge_pages_per_process, ++ "Maximum number of huge pages enabled for each process"); ++ ++/* Version 0.7.1: ++ * - Slab caching in user space introduced; ++ * - Slab hash introduced for fast searching; ++ * - Performance optimizations; ++ * - Adding huge pages support. ++ */ ++static const char VERSION_STRING[]="Version 0.7.1"; ++ ++static DEFINE_MUTEX(dev_mem_lock); ++static user_mem_dev_t *mem_dev_numa = NULL; ++ ++/*directory entry structure for debug root directory and debug file*/ ++static struct dentry *qae_dbg_root_dir = NULL; ++static struct dentry *qae_dbg_slabs_file = NULL; ++ ++typedef struct chr_drv_info_s ++{ ++ unsigned major; ++ unsigned min_minor; ++ unsigned max_minor; ++ char *name; ++ struct cdev drv_cdev; ++ struct class *drv_class; ++ struct device *drv_class_dev; ++ unsigned num_devices; ++ unsigned unregistered; ++} chr_drv_info_t; ++ ++typedef struct { ++ kdev_mem_info_t *head; ++ kdev_mem_info_t *tail; ++} slab_list_t; ++/* Kernel space hash for fast slab searching */ ++static slab_list_t g_slab_list[PAGE_SIZE] = {{0}}; ++ ++extern int handle_other_ioctls(uint32_t cmd); ++/****************************************************************************** ++ * debug: /sys/kernel/debug/qae_mem_dbg directory ++ * qae_mem_slabs file ++ * cat qae_mem_slabs shows the allocated slabs for each process with the ++ * physical and virtual start address ++ * echo "d processid virt_addr" > qae_mem_slabs ++ * echo "d processid phys_addr" > qae_mem_slabs ++ * write dump command to debug file, the next cat qae_mem_slabs command ++ * shows the 256 byte from address in hex and ascii format ++ * echo "c processid slabid" > qae_mem_slabs ++ * write dump command to debug file, the next cat qae_mem_slabs command ++ * shows the 32 x 64 allocation bit map for small buffers allocations ++ ******************************************************************************/ ++ ++/***************************************************************************** ++ memory mgt code begin ++*****************************************************************************/ ++ ++static inline uint64_t get_key(const uint64_t phys) ++{ ++ /* Use bits 20-31 of a physical address as a hash key. ++ * It provides a good distribution for 1Mb/2Mb slabs ++ * and a moderate distribution for 128Kb/256Kb/512Kb slabs. ++ */ ++ return (phys >> 20) & ~PAGE_MASK; ++} ++ ++static inline void add_slab_to_hash(kdev_mem_info_t *slab) ++{ ++ const size_t key = get_key(slab->phy_addr); ++ ++ ADD_ELEMENT_TO_HEAD_LIST(slab, g_slab_list[key].head, ++ g_slab_list[key].tail, _kernel_hash); ++} ++ ++static inline void del_slab_from_hash(kdev_mem_info_t *slab) ++{ ++ const size_t key = get_key(slab->phy_addr); ++ ++ REMOVE_ELEMENT_FROM_LIST(slab, g_slab_list[key].head, ++ g_slab_list[key].tail, _kernel_hash); ++} ++ ++static inline kdev_mem_info_t *find_slab(const uint64_t phy_addr) ++{ ++ const size_t key = get_key(phy_addr); ++ kdev_mem_info_t *slab = g_slab_list[key].head; ++ ++ while (slab) ++ { ++ if (phy_addr == slab->phy_addr) ++ return slab; ++ slab = slab->pNext_kernel_hash; ++ } ++ ++ return NULL; ++} ++ ++/* ++ * Find memory information ++ */ ++static kdev_mem_info_t* ++userMemGetInfo(struct file* fp, uint64_t id) ++{ ++ user_proc_mem_list_t* list = NULL; ++ if(!fp) ++ { ++ mm_err("%s:%d Invalid file pointer\n",__func__,__LINE__ ); ++ return NULL; ++ } ++ list = (user_proc_mem_list_t*)fp->private_data; ++ if(!list) ++ { ++ mm_info("%s:%d empty list\n",__func__,__LINE__); ++ return NULL; ++ } ++ return find_slab(id); ++} ++/* ++ * Allocate numa memory ++ */ ++static dev_mem_info_t * ++userMemAlloc(struct file* fp, size_t size, ++ int node, int large_memory) ++{ ++ block_ctrl_t *block_ctrl = NULL; ++ dev_mem_info_t *mem_info = NULL; ++ kdev_mem_info_t *kmem = NULL; ++ user_proc_mem_list_t *list = NULL; ++ void *phy_addr = NULL; ++ size_t totalInKBytes = 0; ++ ++ if(!size || !fp) ++ { ++ mm_err("%s:%d Invalid parameter value [%zu] %p\n", ++ __func__, __LINE__, size, fp); ++ return NULL; ++ } ++ ++ if(node != NUMA_NO_NODE) ++ { ++ /* node 0.. (MAX_NUMNODES-1) */ ++ if(node >= 0 && node < MAX_NUMNODES) ++ { ++ if(!node_online(node)) ++ { ++ mm_err("%s:%d Requested node %d is not online. " ++ "Using node 0 as default\n", ++ __func__, __LINE__,node); ++ node = 0; ++ } ++ } ++ else ++ { ++ /*greater than MAX_NUMNODES */ ++ mm_err("%s:%d Requested node %d not present. " ++ "Using node 0 as default\n", ++ __func__, __LINE__,node); ++ node = 0; ++ } ++ } ++ ++ /* ++ * Find the process allocation list ++ */ ++ list = (user_proc_mem_list_t*)fp->private_data; ++ if (!list) ++ { ++ mm_err("%s:%d User process memory list is NULL \n",__func__,__LINE__); ++ return NULL; ++ } ++ ++ size = icp_iommu_get_remapping_size(size); ++ totalInKBytes = DIV_ROUND_UP(mem_allocated + size, QAE_KBYTE); ++ ++ /* for request > 2M mem_info control block allocated separately */ ++ if(large_memory) ++ { ++ /*one page is used for block control information*/ ++ const uint32_t pageSizeInKb = PAGE_SIZE / QAE_KBYTE; ++ if ( max_mem_numa && max_mem_numa < (totalInKBytes + pageSizeInKb)) ++ { ++ mm_err(KERN_ERR "%s:%d Maximum NUMA allocation of %u kB reached " ++ "currently allocated %zu bytes requested %zu bytes\n", ++ __func__,__LINE__,max_mem_numa, ++ mem_allocated , (size_t)(size + PAGE_SIZE) ); ++ return NULL; ++ } ++ mem_info = (dev_mem_info_t*) get_zeroed_page(GFP_KERNEL); ++ if ( !mem_info ) ++ { ++ mm_err("%s:%d Unable to allocate control block\n", ++ __func__,__LINE__); ++ return NULL; ++ } ++ kmem = kmalloc (sizeof(kdev_mem_info_t), GFP_KERNEL); ++ if ( !kmem ) ++ { ++ mm_err("%s:%d Unable to allocate Kernel control block\n", ++ __func__,__LINE__); ++ free_page((unsigned long) mem_info); ++ return NULL; ++ } ++ /* kmalloc is faster than kzalloc */ ++ kmem->kmalloc_ptr = kmalloc_node(size, GFP_KERNEL, node); ++ if (!kmem->kmalloc_ptr || !IS_PAGE_ALIGNED(kmem->kmalloc_ptr)) ++ { ++ mm_err("%s:%d Unable to allocate memory slab size %zu" ++ " or wrong alignment: %p\n", ++ __func__, __LINE__, size, kmem->kmalloc_ptr); ++ FREE(kmem->kmalloc_ptr); ++ FREE(kmem); ++ free_page((unsigned long) mem_info); ++ return NULL; ++ } ++ /* Initialize the huge page control */ ++ kmem->huge_mem_ctrl = mem_info; ++ /* Update slab size */ ++ kmem->size = size; ++ /* Update allocated size */ ++ mem_allocated += (size + PAGE_SIZE); ++ } ++ else ++ { ++ if ( max_mem_numa && max_mem_numa < totalInKBytes ) ++ { ++ mm_err(KERN_ERR "%s:%d Maximum NUMA allocation of %u kB reached" ++ " currently allocated %zu bytes requested %zu bytes\n", ++ __func__, __LINE__, max_mem_numa, ++ mem_allocated, size); ++ return NULL; ++ } ++ block_ctrl = kmalloc_node(size, GFP_KERNEL, node); ++ if (!block_ctrl || !IS_PAGE_ALIGNED(block_ctrl)) ++ { ++ mm_err("%s:%d Unable to allocate memory slab" ++ " or wrong alignment: %p\n", ++ __func__, __LINE__, block_ctrl); ++ FREE(block_ctrl); ++ return NULL; ++ } ++ ++ kmem = kmalloc (sizeof(kdev_mem_info_t), GFP_KERNEL); ++ if ( !kmem ) ++ { ++ mm_err("%s:%d Unable to allocate Kernel control block\n", ++ __func__,__LINE__); ++ FREE(block_ctrl); ++ return NULL; ++ } ++ ++ /* It is faster to alloc a slab and memset it later vs. kZalloc_node. */ ++ memset(block_ctrl, 0, sizeof(block_ctrl_t)); ++ mem_info = &block_ctrl->mem_info; ++ kmem->kmalloc_ptr = block_ctrl; ++ /* Huge page control block not applicable here for small slabs. */ ++ kmem->huge_mem_ctrl = NULL; ++ /* Update slab size */ ++ kmem->size = size; ++ /* Update allocated size */ ++ mem_allocated += size; ++ } ++ mem_info->nodeId = node; ++ mem_info->size = size; ++ mem_info->type = large_memory; ++#ifdef ICP_IOMMU_DISABLED ++ icp_iommu_map(&phy_addr, kmem->kmalloc_ptr, mem_info->size); ++#else ++ if (icp_iommu_map(&phy_addr, kmem->kmalloc_ptr, mem_info->size)) ++ { ++ mm_err("%s:%d iommu map failed\n",__func__,__LINE__); ++ if( LARGE == mem_info->type ) ++ { ++ free_page((unsigned long) mem_info); ++ mem_allocated -= PAGE_SIZE; ++ } ++ /* For small block size, kmalloc_ptr points to block_ctrl */ ++ FREE(kmem->kmalloc_ptr); ++ FREE(kmem); ++ mem_allocated -= size; ++ return NULL; ++ } ++#endif ++ mem_info->phy_addr = (uintptr_t) phy_addr; ++ kmem->phy_addr = (uintptr_t) phy_addr; ++ list->allocs_nr++; ++ ADD_ELEMENT_TO_END_LIST(kmem, list->head, list->tail, _kernel); ++ add_slab_to_hash(kmem); ++ ++ return mem_info; ++} ++/* ++ * Free slab ++ */ ++static void ++free_slab(user_proc_mem_list_t *list, kdev_mem_info_t *slab, ++ const int cleanup) ++{ ++ void *ptr = slab->kmalloc_ptr; ++ const size_t size = slab->size; ++ ++ icp_iommu_unmap((void *) (uintptr_t) slab->phy_addr, size); ++ REMOVE_ELEMENT_FROM_LIST(slab, list->head, list->tail, _kernel); ++ ++ del_slab_from_hash(slab); ++ ++ /* If we are dealing with huge pages, then huge_mem_ctrl is not NULL ++ * and the slab can be freed. ++ */ ++ if(slab->huge_mem_ctrl) ++ { ++ free_page((unsigned long) slab->huge_mem_ctrl); ++ mem_allocated -= PAGE_SIZE; ++ } ++ ++ if (cleanup) ++ { ++ /* Cleanup released memory. */ ++ memset(ptr, 0, size); ++ } ++ FREE(ptr); ++ ++ /* Destroy the slab as it is no longer needed */ ++ FREE(slab); ++ ++ mem_allocated -= size; ++ list->allocs_nr -= 1; ++} ++/* ++ * Free memory ++ */ ++static int ++userMemFree(struct file* fp, uint64_t id) ++{ ++ user_proc_mem_list_t* list = NULL; ++ kdev_mem_info_t *kmem = NULL; ++ ++ if (!fp) ++ { ++ mm_err("%s:%d Invalid file pointer\n",__func__,__LINE__); ++ return -EIO; ++ } ++ list = (user_proc_mem_list_t *)fp->private_data; ++ if(!list) ++ { ++ mm_warning("%s:%d No slab to free\n",__func__,__LINE__); ++ return -EIO; ++ } ++ kmem = find_slab(id); ++ if (kmem) ++ { ++ /* Free memory slab, no cleanup. */ ++ free_slab(list, kmem, 0); ++ return 0; ++ } ++ mm_warning("%s:%d Could not find slab with id: %llu \n", ++ __func__,__LINE__,id); ++ return -EIO; ++} ++/* ++ * Clean all memory for a process ++ */ ++static int ++userMemFreeSlabs(struct file* fp) ++{ ++ kdev_mem_info_t* kmem = NULL, *next = NULL; ++ user_proc_mem_list_t* list = NULL; ++ ++ if (!fp) ++ { ++ mm_err("%s:%d Invalid file pointer\n",__func__,__LINE__); ++ return -EIO; ++ } ++ list = (user_proc_mem_list_t*)fp->private_data; ++ if(!list) ++ { ++ mm_warning("%s:%d No slab to free\n",__func__,__LINE__); ++ return -EIO; ++ } ++ max_huge_pages += list->hugepages_nr; ++#ifdef ICP_DEBUG ++ mm_info("[FREE] pid: %u return number of pages: %llu total number: %u\n", ++ current->pid, ++ list->hugepages_nr, ++ max_huge_pages); ++#endif ++ list->hugepages_nr = 0; ++ kmem = list->head; ++ while(kmem) ++ { ++#ifdef ICP_DEBUG ++ mm_warning("%s:%d Potential memory leak, Process Id %d " ++ "Virtual address %p " ++ "Physical address %px has allocated block\n", ++ __func__,__LINE__, ++ list->pid, ++ kmem->kmalloc_ptr, ++ (void*)kmem->phy_addr); ++#endif ++ next = kmem->pNext_kernel; ++ /* Free and cleanup memory slab. */ ++ free_slab(list, kmem, 1); ++ kmem = next; ++ } ++ return 0; ++} ++ ++/***************************************************************************** ++ memory mgt code end ++*****************************************************************************/ ++ ++static int ++dev_mem_alloc(struct file* fp, uint32_t cmd, unsigned long arg) ++{ ++ unsigned long ret = 0; ++ dev_mem_info_t* mem_info = NULL; ++ dev_mem_info_t user_mem_info = {0}; ++ ++ if( fp == NULL ) ++ { ++ mm_err("%s:%d Invalid file descriptor\n",__func__,__LINE__); ++ return -EIO; ++ } ++ if( fp->private_data == NULL) ++ { ++ mm_err("%s:%d Invalid file private data \n",__func__,__LINE__); ++ return -EIO; ++ } ++ ret = copy_from_user(&user_mem_info, ++ (dev_mem_info_t *)arg, ++ sizeof(dev_mem_info_t)); ++ if (unlikely(ret)) ++ { ++ mm_err("%s:%d copy_from_user failed, ret=%lu\n", ++ __func__,__LINE__,ret); ++ return -EIO; ++ } ++ mem_info = userMemAlloc(fp, user_mem_info.size, ++ (int) user_mem_info.nodeId, ++ user_mem_info.type); ++ if (!mem_info) ++ { ++ mm_err("%s:%d userMemAlloc failed\n",__func__,__LINE__); ++ return -ENOMEM; ++ } ++ ret = copy_to_user((dev_mem_info_t *)arg, ++ mem_info, ++ sizeof(dev_mem_info_t)); ++ if (unlikely(ret)) ++ { ++ (void) userMemFree(fp, user_mem_info.phy_addr); ++ mm_err("%s:%d copy_to_user failed, ret=%lu\n", ++ __func__,__LINE__,ret); ++ return -EIO; ++ } ++ return 0; ++} ++ ++static int ++dev_mem_free(struct file *fp, uint32_t cmd, unsigned long arg) ++{ ++ unsigned long ret = 0; ++ dev_mem_info_t user_mem_info = {0}; ++ ++ if( fp == NULL ) ++ { ++ mm_err("%s:%d Invalid file descriptor\n",__func__,__LINE__); ++ return -EIO; ++ } ++ if( fp->private_data == NULL) ++ { ++ mm_err("%s:%d Invalid file private data\n",__func__,__LINE__); ++ return -EIO; ++ } ++ ret = copy_from_user(&user_mem_info, ++ (dev_mem_info_t *)arg, ++ sizeof(dev_mem_info_t)); ++ if (ret) ++ { ++ mm_err("%s:%d dev_mem_free: copy_from_user failed, ret=%lu\n", ++ __func__,__LINE__,ret); ++ return -EIO; ++ } ++ return userMemFree(fp, user_mem_info.phy_addr); ++} ++ ++static int ++dev_release_pid(struct file *fp, uint32_t cmd, unsigned long arg) ++{ ++ return userMemFreeSlabs(fp); ++} ++static int ++dev_get_user_page(struct file *fp, uint32_t cmd, unsigned long arg) ++{ ++ unsigned long ret; ++ struct page *page; ++ int errno = 0; ++ user_page_info_t user_mem_info = {0}; ++ ++ if( fp == NULL ) ++ { ++ mm_err("%s:%d Invalid file descriptor\n",__func__,__LINE__); ++ return -EIO; ++ } ++ if( fp->private_data == NULL) ++ { ++ mm_err("%s:%d Invalid file private data\n",__func__,__LINE__); ++ return -EIO; ++ } ++ ret = copy_from_user(&user_mem_info, (user_page_info_t *)arg, ++ sizeof(user_page_info_t)); ++ if (ret) ++ { ++ mm_err("%s:%d dev_get_user_page: copy_from_user failed, ret=%lu\n", ++ __func__,__LINE__,ret); ++ return -EIO; ++ } ++ ++ errno = get_user_pages_fast( ++ (unsigned long)user_mem_info.virt_addr, 1, 1, &page); ++ if ( errno != 1 ) ++ { ++ user_mem_info.phy_addr = 0x00; ++ mm_err("%s:%d dev_get_user_page: get_user_pages_fast failed, ret=%d\n", ++ __func__,__LINE__,errno); ++ return -EIO; ++ } ++ else ++ { ++ if (PageHuge(page)) ++ { ++ user_mem_info.phy_addr = page_to_phys(page); ++ } ++ else ++ { ++ user_mem_info.phy_addr = 0x00; ++ } ++ ++ } ++ put_page(page); ++ ++ ret = copy_to_user( (user_page_info_t *)arg, &user_mem_info, ++ sizeof(user_page_info_t)); ++ if (ret) ++ { ++ mm_err("%s:%d dev_get_user_page: copy_to_user failed, ret=%lu\n", ++ __func__,__LINE__,ret); ++ return -EIO; ++ } ++ return 0; ++} ++ ++static int ++dev_num_hp_get(struct file *fp, uint32_t cmd, unsigned long arg) ++{ ++ unsigned long ret = 0; ++ uint actual_num_hugepages = 0; ++ ++ if( fp == NULL ) ++ { ++ mm_err("%s:%d Invalid file descriptor\n",__func__,__LINE__); ++ return -EIO; ++ } ++ if( fp->private_data == NULL) ++ { ++ mm_err("%s:%d Invalid file private data\n",__func__,__LINE__); ++ return -EIO; ++ } ++ actual_num_hugepages = min(max_huge_pages, max_huge_pages_per_process); ++ ret = copy_to_user((uint32_t *)arg, ++ &actual_num_hugepages, ++ sizeof(uint32_t)); ++ if (ret) ++ { ++ mm_err("%s:%d dev_num_hp_get: copy_to_user failed, ret=%lu\n", ++ __func__,__LINE__,ret); ++ return -EIO; ++ } ++ max_huge_pages -= actual_num_hugepages; ++ ((user_proc_mem_list_t*)fp->private_data)->hugepages_nr = ++ actual_num_hugepages; ++#ifdef ICP_DEBUG ++ mm_info("[ALLOC] pid: %u max_huge_pages: %u actual_num_hugepages: %u\n", ++ current->pid, ++ max_huge_pages, ++ actual_num_hugepages); ++#endif ++ return 0; ++} ++ ++static long ++mem_ioctl(struct file *fp, uint32_t cmd, unsigned long arg) ++{ ++ int ret = 0; ++ switch(cmd) { ++ case DEV_MEM_IOC_MEMALLOC: ++ mutex_lock(&dev_mem_lock); ++ ret = dev_mem_alloc(fp, cmd, arg); ++ mutex_unlock(&dev_mem_lock); ++ if (ret) ++ { ++ return -ENOMEM; ++ } ++ break; ++ ++ case DEV_MEM_IOC_MEMFREE: ++ mutex_lock(&dev_mem_lock); ++ ret = dev_mem_free(fp, cmd, arg); ++ mutex_unlock(&dev_mem_lock); ++ if (unlikely(ret)) ++ { ++ return -EIO; ++ } ++ break; ++ ++ case DEV_MEM_IOC_RELEASE: ++ mutex_lock(&dev_mem_lock); ++ ret = dev_release_pid(fp, cmd, arg); ++ mutex_unlock(&dev_mem_lock); ++ if (unlikely(ret)) ++ { ++ return -EIO; ++ } ++ break; ++ ++ case DEV_MEM_IOC_GET_NUM_HPT: ++ mutex_lock(&dev_mem_lock); ++ ret = dev_num_hp_get(fp, cmd, arg); ++ mutex_unlock(&dev_mem_lock); ++ if (unlikely(ret)) ++ { ++ return -EIO; ++ } ++ break; ++ ++ case DEV_MEM_IOC_GET_USER_PAGE: ++ mutex_lock(&dev_mem_lock); ++ ret = dev_get_user_page(fp, cmd, arg); ++ mutex_unlock(&dev_mem_lock); ++ if (unlikely(ret)) ++ { ++ return -EIO; ++ } ++ break; ++ ++ default: ++ ret = handle_other_ioctls(cmd); ++ return ret; ++ } ++ return 0; ++} ++ ++static int cmd_mmap_access(struct vm_area_struct *vma, ++ unsigned long addr, void *buf, int len, int write) ++{ ++ int size = vma->vm_end - addr; ++ unsigned long offs = addr - vma->vm_start; ++ unsigned long phy_addr = vma->vm_pgoff << PAGE_SHIFT; ++ void *virt_addr = phys_to_virt(phy_addr); ++ ++ len = min(len, size); ++ ++ if (write) ++ memcpy(virt_addr + offs, buf, len); ++ else ++ memcpy(buf, virt_addr + offs, len); ++ ++ return len; ++} ++ ++static struct vm_operations_struct cmd_mmap_operations = { ++ .access = cmd_mmap_access, ++}; ++ ++static int ++mem_mmap(struct file *fp, struct vm_area_struct *vma) ++{ ++ int ret = 0; ++ uint64_t id = 0; ++ unsigned long phys_kmalloc_area = 0; ++ kdev_mem_info_t *kmem = NULL; ++ unsigned long size = vma->vm_end - vma->vm_start; ++ id = vma->vm_pgoff << PAGE_SHIFT; ++ ++ mutex_lock(&dev_mem_lock); ++ kmem = userMemGetInfo(fp, id); ++ if (!kmem) ++ { ++ mutex_unlock(&dev_mem_lock); ++ mm_err("%s:%d cannot find meminfo\n",__func__,__LINE__); ++ return -ENOMEM; ++ } ++ ++ /* Ensure memory mapping does not exceed the allocated memory region */ ++ if (size > kmem->size) ++ { ++ mutex_unlock(&dev_mem_lock); ++ mm_err("%s:%d cannot map allocated memory region\n", ++ __func__, __LINE__); ++ return -ENOMEM; ++ } ++ ++ /* There is an agreement that mmap(PAGE_SIZE) means control block. */ ++ if (PAGE_SIZE == size) ++ { ++ phys_kmalloc_area = virt_to_phys(kmem->huge_mem_ctrl); ++ } ++ /* Any other size means memory block. */ ++ else ++ { ++ phys_kmalloc_area = virt_to_phys(kmem->kmalloc_ptr); ++ } ++ mutex_unlock(&dev_mem_lock); ++ ++ vma->vm_ops = &cmd_mmap_operations; ++ ret = remap_pfn_range(vma, ++ vma->vm_start, ++ phys_kmalloc_area >> PAGE_SHIFT, ++ size, ++ vma->vm_page_prot); ++ if (unlikely(ret)) ++ { ++ mm_err("%s:%d remap_pfn_range failed, ret = %d\n", ++ __func__,__LINE__,ret); ++ } ++ return ret; ++} ++static int ++mem_open(struct inode *inp, struct file *fp) ++{ ++ user_proc_mem_list_t *list = NULL; ++ mutex_lock(&dev_mem_lock); ++ if (!fp->private_data) ++ { ++ list = kzalloc(sizeof(user_proc_mem_list_t), GFP_KERNEL); ++ if(!list) ++ { ++ mm_err("%s:%d memory allocation failed\n", ++ __func__,__LINE__); ++ mutex_unlock(&dev_mem_lock); ++ return -ENODEV; ++ } ++ fp->private_data = list; ++ ADD_ELEMENT_TO_END_LIST(list, mem_dev_numa->head, ++ mem_dev_numa->tail, ); ++ list->pid = current->tgid; ++ } ++ mutex_unlock(&dev_mem_lock); ++ return 0; ++} ++ ++static inline void remove_element(user_proc_mem_list_t * p) ++{ ++ if (NULL == p) ++ return; ++ if (NULL != p->pPrev) { ++ p->pPrev->pNext = p->pNext; ++ } ++ if (NULL != p->pNext) { ++ p->pNext->pPrev = p->pPrev; ++ } ++} ++ ++static int ++mem_release(struct inode *inp, struct file *fp) ++{ ++ user_proc_mem_list_t *list = NULL; ++ mutex_lock(&dev_mem_lock); ++ list=(user_proc_mem_list_t *)fp->private_data; ++ if( list ) ++ { ++ (void)userMemFreeSlabs(fp); ++ if (NULL != mem_dev_numa) ++ { ++ REMOVE_ELEMENT_FROM_LIST(list, ++ mem_dev_numa->head, mem_dev_numa->tail, ); ++ } ++ else ++ { ++ remove_element(list); ++ } ++ FREE(list); ++ fp->private_data=NULL; ++ } ++ mutex_unlock(&dev_mem_lock); ++ return 0; ++} ++ ++static struct file_operations mem_ops = { ++ owner:THIS_MODULE, ++ mmap:mem_mmap, ++ unlocked_ioctl:mem_ioctl, ++ compat_ioctl:mem_ioctl, ++ open:mem_open, ++ release:mem_release, ++}; ++ ++static chr_drv_info_t mem_drv_info = { ++ major:0, ++ min_minor:DEV_MEM_BASE_MINOR, ++ max_minor:DEV_MEM_MAX_MINOR, ++ name:DEV_MEM_NAME, ++}; ++ ++static int32_t ++chr_drv_create_class(chr_drv_info_t* drv_info) ++{ ++ QAE_LOCAL_ENSURE(drv_info, ++ "chr_drv_create_class(): Invalid parameter value ", ++ -EINVAL); ++ ++ drv_info->drv_class = class_create(THIS_MODULE, drv_info->name); ++ if (IS_ERR(drv_info->drv_class)) ++ { ++ mm_err("%s:%d class_create failed\n",__func__,__LINE__); ++ return -ENODEV; ++ } ++ return 0; ++} ++ ++static void ++chr_drv_destroy_class(chr_drv_info_t* drv_info) ++{ ++ if (NULL == drv_info) ++ { ++ mm_err("%s:%d Invalid parameter value\n",__func__,__LINE__); ++ return; ++ }; ++ class_destroy( drv_info->drv_class ); ++ drv_info->drv_class = NULL; ++ return; ++} ++ ++static inline void ++chr_drv_destroy_device(chr_drv_info_t *drv_info) ++{ ++ if (NULL == drv_info) ++ { ++ mm_err("%s:%d Invalid parameter value\n",__func__,__LINE__); ++ return; ++ } ++ if (NULL != drv_info->drv_class_dev) ++ { ++ device_destroy(drv_info->drv_class, MKDEV(drv_info->major, ++ DEV_MEM_BASE_MINOR)); ++ } ++ cdev_del(&(drv_info->drv_cdev)); ++ unregister_chrdev_region( MKDEV(drv_info->major, DEV_MEM_BASE_MINOR), ++ drv_info->max_minor); ++ return; ++} ++ ++static int ++chr_drv_create_device(chr_drv_info_t *drv_info) ++{ ++ int ret = 0; ++ dev_t devid = 0; ++ ++ QAE_LOCAL_ENSURE(drv_info, ++ "chr_drv_create_device(): Invalid parameter value ", ++ -ENODEV); ++ ret = alloc_chrdev_region(&devid, ++ drv_info->min_minor, ++ drv_info->max_minor, ++ drv_info->name); ++ if (unlikely(ret)) ++ { ++ mm_err("%s:%d Unable to allocate chrdev region\n", ++ __func__,__LINE__); ++ return -ENOMEM; ++ } ++ drv_info->major = MAJOR(devid); ++ drv_info->drv_cdev.owner=THIS_MODULE; ++ cdev_init(&(drv_info->drv_cdev), &mem_ops); ++ ret = cdev_add(&(drv_info->drv_cdev), devid, drv_info->max_minor); ++ if (unlikely(ret)) ++ { ++ mm_err("%s:%d cdev add failed\n",__func__,__LINE__); ++ chr_drv_destroy_device(drv_info); ++ return -ENOENT; ++ } ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) ++ drv_info->drv_class_dev = device_create(drv_info->drv_class, ++ NULL, MKDEV(drv_info->major, DEV_MEM_BASE_MINOR), ++ NULL, "%s", drv_info->name); ++#else ++ drv_info->drv_class_dev = device_create(drv_info->drv_class, ++ NULL, MKDEV(drv_info->major, DEV_MEM_BASE_MINOR), ++ drv_info->name); ++#endif ++ if( NULL == drv_info->drv_class_dev ) ++ { ++ mm_err("%s:%d device_create failed\n",__func__,__LINE__); ++ chr_drv_destroy_device(drv_info); ++ return -ENOMEM; ++ } ++ return 0; ++} ++ ++static int32_t register_mem_device_driver(void) ++{ ++ int ret = 0; ++ mutex_init(&dev_mem_lock); ++ mem_dev_numa = kzalloc(sizeof(user_mem_dev_t), GFP_KERNEL); ++ if(!mem_dev_numa) ++ { ++ mm_err("failed to allocate memory for numa mem device\n"); ++ return -ENOMEM; ++ } ++ ret = chr_drv_create_class(&mem_drv_info); ++ if(unlikely(ret)) ++ { ++ mm_err("failed to create device driver class\n"); ++ FREE(mem_dev_numa); ++ return -ENODEV; ++ } ++ ret = chr_drv_create_device(&mem_drv_info); ++ if(unlikely(ret)) ++ { ++ mm_err("failed to create mem numa device driver\n"); ++ chr_drv_destroy_class(&mem_drv_info); ++ FREE(mem_dev_numa); ++ return -ENODEV; ++ } ++ mem_drv_info.unregistered = 0; ++ return 0; ++} ++/* ++ * unregister the device driver ++ */ ++static void unregister_mem_device_driver(void) ++{ ++ if(!mem_drv_info.unregistered) ++ { ++ chr_drv_destroy_device(&mem_drv_info); ++ chr_drv_destroy_class(&mem_drv_info); ++ FREE(mem_dev_numa); ++ mem_dev_numa = NULL; ++ mem_drv_info.unregistered = 1; ++ } ++} ++ ++static inline char printable(char sym) ++{ ++ if (sym >= 0x20 && sym <= 0x7E) ++ /*check if printable ascii*/ ++ return sym; ++ else ++ /*else put out a dot*/ ++ return '.'; ++} ++ ++static char qae_dbg_ascii[128]; ++static char qae_dbg_command[128]; ++static char qae_dbg_slab_data[4096]; ++/*dumps memory data in 16 8 hex bytes and 8 ascii chars columns and 32 rows*/ ++static int ++dumpData(void *start, void *end) ++{ ++ int row = 0; ++ int col = 0; ++ char *src = start; ++ char *endaddr = end; ++ size_t offs = 0; ++ const int ROWS = 32; ++ const int COLUMNS = 8; ++ ++ for (row = 0; row < ROWS; ++row) ++ { ++ size_t ascii = 0; ++ ++ for (col = 0; col < COLUMNS; ++col) ++ { ++ if (src > endaddr) ++ { ++ offs += scnprintf(qae_dbg_slab_data + offs, ++ sizeof(qae_dbg_slab_data) - offs, " "); ++ ascii += scnprintf(qae_dbg_ascii + ascii, ++ sizeof(qae_dbg_ascii) - ascii, " "); ++ } ++ else ++ { ++ /*in the first 8 columns print bytes in hex with 2 nibbles*/ ++ offs += scnprintf(qae_dbg_slab_data + offs, ++ sizeof(qae_dbg_slab_data) - offs, "%02hhx ", *src); ++ /*in the last 8 columns print ascii char or dot*/ ++ ascii += scnprintf(qae_dbg_ascii + ascii, ++ sizeof(qae_dbg_ascii) - ascii, "%c ", printable(*src)); ++ src++; ++ } ++ } ++ offs += scnprintf(qae_dbg_slab_data + offs, ++ sizeof(qae_dbg_slab_data) - offs, "%.128s\n", qae_dbg_ascii); ++ if (src > endaddr) ++ return offs; ++ } ++ return offs; ++} ++/* ++ * findSlabsForPid - find the link list of slabs for a given pid ++ */ ++static kdev_mem_info_t* ++findSlabsForPid(const uint64_t pid) ++{ ++ if (mem_dev_numa) ++ { ++ user_proc_mem_list_t *list = mem_dev_numa->head; ++ while (list) ++ { ++ if (list->pid == pid ) ++ return list->head; ++ list=list->pNext; ++ } ++ } ++ return NULL; ++} ++/* ++ * execute dump command ++ * returns length of data in output buffer ++ */ ++static int ++execDump(kdev_mem_info_t* slab, const uintptr_t param, const uint64_t pid) ++{ ++ uintptr_t endaddr = 0; ++ uintptr_t startaddr = param; ++ uintptr_t offset = 0; ++ size_t len = 0; ++ ++ mm_info("Process dump command \n"); ++ /* traverse thru slabs */ ++ while (slab) ++ { ++ uintptr_t phy_addr = (uintptr_t) slab->phy_addr; ++ uintptr_t virt_addr = (uintptr_t) slab->kmalloc_ptr; ++ /*calculate virtual address end of slab*/ ++ endaddr = virt_addr + slab->size; ++ /*check if this slab was sought after by virtual address*/ ++ if (startaddr >= virt_addr && startaddr < endaddr) ++ { ++ offset = startaddr - virt_addr; ++ mm_info("Block found: " ++ "start %p block end %p dump addr %p offset %p\n", ++ (void *) virt_addr, (void *) endaddr, ++ (void *) startaddr, (void *) offset); ++ break; ++ } ++ /*calculate physical address end of slab*/ ++ endaddr = phy_addr + slab->size; ++ /*check if this slab was sought after by phy address*/ ++ if (startaddr >= phy_addr && startaddr < endaddr) ++ { ++ offset = startaddr - phy_addr; ++ mm_info("Block found (using phy_addr): " ++ "start %p block end %p dump addr %p offset %p\n", ++ (void *) phy_addr, (void *) endaddr, ++ (void *) startaddr, (void *) offset); ++ break; ++ } ++ /* take next slab if no hit */ ++ slab = slab->pNext_kernel; ++ } ++ /* log slab not found */ ++ if( !slab ) ++ { ++ len = scnprintf(qae_dbg_slab_data, sizeof(qae_dbg_slab_data), ++ "Slab not found PID %llu Address %p\n", ++ pid, (void *) startaddr); ++ } ++ else /*dump 256 byte of slab data */ ++ { ++ startaddr = (uintptr_t) slab + offset; ++ endaddr = (uintptr_t) slab + ++ slab->size - 1; ++ len = dumpData((void *) startaddr, (void *) endaddr); ++ } ++ return len; ++} ++/* ++ * execute dump control area command ++ * returns length of data in output buffer ++ */ ++static int32_t ++execDumpControl(kdev_mem_info_t* slab, const uintptr_t param, const uint64_t pid) ++{ ++ uint64_t id = param; ++ uintptr_t endaddr = 0; ++ size_t len = 0; ++ ++ /*traverse thru slabs search by slab id*/ ++ while(slab) ++ { ++ endaddr = slab->phy_addr + slab->size; ++ if (id >= slab->phy_addr && id < endaddr) ++ { ++ break; ++ } ++ slab = slab->pNext_kernel; ++ } ++ if( !slab ) /* log slab not found*/ ++ { ++ len = scnprintf(qae_dbg_slab_data, sizeof(qae_dbg_slab_data), ++ "Slab not found PID %llu slab ID %llu\n", pid, id); ++ } ++ else /*dump bitmap*/ ++ { ++ int row; ++ uint64_t bitmap_row,mask; ++ /* banner message */ ++ len = scnprintf(qae_dbg_slab_data, sizeof(qae_dbg_slab_data), ++ "Small buffer allocation bitmap \n Slab id %llu \n", id); ++ /* display 0/1 in bitmap positions throughout the bitmap */ ++ for ( row = 0; row < BITMAP_LEN; ++row ) ++ { ++ /* The slab does not contain any bitmap information anymore. ++ * We must now access with kmalloc_ptr */ ++ bitmap_row = ((block_ctrl_t*)slab->kmalloc_ptr)->bitmap[row]; ++ for ( mask = 1ULL<<(QWORD_WIDTH-1); mask; mask>>=1) ++ { ++ char bit = '0'; ++ if ( mask & bitmap_row ) ++ { ++ bit = '1'; ++ } ++ len += scnprintf(qae_dbg_slab_data + len, ++ sizeof(qae_dbg_slab_data) - len, "%c", bit); ++ } ++ len += scnprintf(qae_dbg_slab_data + len, ++ sizeof(qae_dbg_slab_data) - len, "\n"); ++ } ++ } ++ return len; ++} ++/* processCommand ++ * performs the command found in the command buffer ++ * returns the number of characters the debug ++ * buffer has after command was executed ++ */ ++static int ++processCommand(void) ++{ ++ char *arg = NULL; ++ char *cmd = NULL; ++ char command = '\0'; /*command char c/d*/ ++ uint64_t param = 0; /*command parameter*/ ++ uint64_t pid = 0; /*process id*/ ++ kdev_mem_info_t* slab = NULL; /*slab the info is required for*/ ++ size_t len = 0; /*length of string in output buffer*/ ++ ++ command = qae_dbg_command[0]; ++ if ('\0' == command) /*check if there is a command*/ ++ { ++ return 0; ++ } ++ /* Search for a first numeric argument after the command itself. */ ++ cmd = strpbrk(qae_dbg_command, "0123456789"); ++ arg = strsep(&cmd, " "); ++ if (NULL != arg) { ++ int status = kstrtoll(arg, 0, &pid); ++ pid *= (status == 0); ++ ++ /* Find a next argument. */ ++ arg = strsep(&cmd, " "); ++ if (NULL != arg) ++ { ++ status = kstrtoll(arg, 0, ¶m); ++ param *= (status == 0); ++ } ++ } ++ mm_info("%s:%d " ++ "Command %c Param %llu %llu Buffer %s Arg %s\n", ++ __func__, __LINE__, command, pid, param, qae_dbg_command, arg); ++ /* Destroy the original command. */ ++ qae_dbg_command[0] = '\0'; ++ ++ switch (command) ++ { ++ case 'd': ++ slab = findSlabsForPid(pid); /* find slab for process id*/ ++ if(!slab) ++ { ++ mm_info("%s:%d " ++ "Could not find slab for process id: %llu\n", ++ __func__,__LINE__,pid); ++ return 0; ++ } ++ /*dump memory content*/ ++ len = execDump(slab,param,pid); ++ break; ++ case 'c': ++ slab = findSlabsForPid(pid); /* find slab for process id*/ ++ if(!slab) ++ { ++ mm_info("%s:%d " ++ "Could not find slab for process id: %llu\n", ++ __func__,__LINE__,pid); ++ return 0; ++ } ++ /* control block data (bitmap) */ ++ len = execDumpControl(slab,param,pid); ++ break; ++ case 't': ++ /* print total allocated NUMA memory */ ++ len = scnprintf(qae_dbg_slab_data, sizeof(qae_dbg_slab_data), ++ "Total allocated NUMA memory: %zu bytes\n", ++ mem_allocated); ++ break; ++ default: ++ len = scnprintf(qae_dbg_slab_data, sizeof(qae_dbg_slab_data), ++ "Invalid command %c\n", command); ++ break; ++ } ++ return len; ++} ++/* print info about a slab in debug buffer ++ * return number of byte in buffer ++ * 0 return value will end the file read operation ++ * each time this function is called one slab data ++ * is entered in the debug buffer ++ * process and slab ptrs are saved in static variables ++ * to traverse the linked list by file read until a 0 ++ * return value is received. ++ */ ++static int ++getMemInfo(user_proc_mem_list_t** pmem_list) ++{ ++ /*memory info for slab in memory list*/ ++ static kdev_mem_info_t* mem_info; ++ /*memory list element of current process*/ ++ user_proc_mem_list_t* mem_list = *pmem_list; ++ int length = 0; ++ /*initialise list of processes that allocated slabs*/ ++ if (!mem_info && !mem_list ) ++ { ++ mem_list = mem_dev_numa->head; ++ /*return if list is empty*/ ++ if ( !mem_list) ++ return 0; ++ mem_info = mem_list->head; ++ } ++ /* iterate through all processes in the list*/ ++ while(mem_list) ++ { ++ /*check if there is a valid slab entry*/ ++ if(mem_info) ++ { ++ length = scnprintf(qae_dbg_slab_data, sizeof(qae_dbg_slab_data), ++ "Pid %d, Slab Id %llu \n" ++ "Virtual address %p, Physical Address %llx, Size %lld\n", ++ mem_list->pid, mem_info->phy_addr, mem_info->kmalloc_ptr, ++ mem_info->phy_addr, mem_info->size); ++ /*advance slab pointer for next call*/ ++ mem_info = mem_info->pNext_kernel; ++ /*send slab info into read buffer*/ ++ break; ++ } ++ else ++ { ++ /* null slab ptr in list of previous process ++ * get next process from list*/ ++ mem_list = mem_list->pNext; ++ /*get first slab from next list element*/ ++ if(mem_list) ++ mem_info = mem_list->head; ++ } ++ } ++ /* if at the end of process list chain*/ ++ if(!mem_list) ++ { ++ mem_list = mem_dev_numa->head; ++ mem_info = NULL; ++ } ++ /* save current process in list in a static for next call*/ ++ *pmem_list = mem_list; ++ return length; ++} ++/* ++*qae_mem_update_slab_data ++* updates data in debug buffer depending on last command ++* open - non-null if called from debug file open routine ++* otherwise 0 ++*/ ++static int ++qae_mem_update_slab_data(int open) ++{ ++ /* memory list of current process*/ ++ static user_proc_mem_list_t* mem_list; ++ static int count; /*number of chars in debug buffer*/ ++ if( !mem_dev_numa ) ++ return 0; ++ /* if file just opened initialise; make sure ++ * list of slabs are generated from the top ++ * if qae_dbg_command buffer is empty */ ++ if(open) ++ { ++ mem_list = NULL; ++ count = 0; ++ return 0; ++ } ++ /* last time a buffer with chars were sent in response to read operation ++ return 0 now to complete read operation.*/ ++ if(count) ++ { ++ count = 0; ++ return 0; ++ } ++ /* process command and report to read op if there is any result*/ ++ count = processCommand(); ++ if(count) ++ return count; ++ /*get next slab info into debug data buffer*/ ++ /* when 0 is returned it marks the end of buffer list*/ ++ /* and will end the file read operation as well*/ ++ return getMemInfo(&mem_list); ++} ++/*read function for debug file ++ returns number of bytes read ++ read operation completes when 0 is returned here*/ ++static ssize_t ++qae_mem_slabs_data_read(struct file* filp, char __user *buffer, ++ size_t count, loff_t * pos) ++{ ++ /*update data in debug buffer*/ ++ int data_len = qae_mem_update_slab_data(false); ++ /*check length and position */ ++ if( 0 == data_len || *pos >= data_len ) ++ return 0; ++ /* Ensure the addition of (*pos + count) does not overflow */ ++ if ((*pos + count) > ULLONG_MAX) ++ return 0; ++ if( *pos + count > data_len ) ++ count = data_len - *pos; ++ /*copy from kernel buffer to user*/ ++ if( copy_to_user(buffer ,qae_dbg_slab_data + *pos, ++ (unsigned)count)) ++ return -EFAULT; ++ return count; ++} ++/*write function for write operation of the debug file*/ ++static ssize_t ++qae_mem_slabs_data_write (struct file *filp, ++ const char __user *buffer, ++ size_t count, loff_t *pos) ++{ ++ /*write command to qae_dbg_command buffer ++ *next read on debug file will parse the command string ++ *and execute the requested command ++ *if command buffer empty the next read ++ *lists the allocated slabs */ ++ /* check count vs size of command buffer*/ ++ if (count >= sizeof(qae_dbg_command) ) ++ { ++ return -EFAULT; ++ } ++ /* copy command string from user buffer*/ ++ if ( copy_from_user(qae_dbg_command, buffer, count) ) ++ { ++ return -EFAULT; ++ } ++ /*terminating 0*/ ++ qae_dbg_command[count] = '\0'; ++ return count; ++} ++/*called when debug file is opened ++ used for initialisation */ ++static int ++qae_mem_slabs_data_open(struct inode *inode, struct file* filep) ++{ ++ qae_mem_update_slab_data(1); ++ return 0; ++} ++static struct file_operations qae_mem_slabs_file_fops = { ++ .owner = THIS_MODULE, ++ .open = qae_mem_slabs_data_open, ++ .read = qae_mem_slabs_data_read, ++ .write = qae_mem_slabs_data_write ++}; ++/* ++ * Initialisation function to insmod device driver ++ */ ++static inline void ++qae_debug_init(void) ++{ ++ if ( ( qae_dbg_root_dir = debugfs_create_dir("qae_mem_dbg", NULL) ) ++ == ERR_PTR(-ENODEV) || ++ ( qae_dbg_slabs_file = debugfs_create_file("qae_mem_slabs", 0666, ++ qae_dbg_root_dir, NULL, ++ &qae_mem_slabs_file_fops) ) == ERR_PTR(-ENODEV) ) ++ { ++ mm_warning( ++ "Debug FS not initialised, debug info not available\n"); ++ } ++} ++ ++static int ++qae_mem_init( void ) ++{ ++ mm_info("Loading %s Module %s ...\n", MODULE_NAME, VERSION_STRING); ++ mm_info("IOCTLs: %lx, %lx, %lx, %lx\n", ++ (unsigned long)DEV_MEM_IOC_MEMALLOC, ++ (unsigned long)DEV_MEM_IOC_MEMFREE, ++ (unsigned long)DEV_MEM_IOC_RELEASE, ++ (unsigned long)DEV_MEM_IOC_GET_NUM_HPT); ++ if(register_mem_device_driver()) ++ { ++ mm_err("Error loading %s Module\n", MODULE_NAME); ++ return -1; ++ } ++ qae_debug_init(); ++ return 0; ++} ++/* ++ * tear down function to rmmod device driver ++ */ ++STATIC void ++qae_mem_exit( void ) ++{ ++ mm_info("Unloading %s Module %s...\n", MODULE_NAME, VERSION_STRING); ++ unregister_mem_device_driver(); ++ if( NULL != qae_dbg_root_dir ) ++ { ++ debugfs_remove_recursive(qae_dbg_root_dir); ++ qae_dbg_root_dir = NULL; ++ } ++} ++module_init(qae_mem_init); ++module_exit(qae_mem_exit); ++ ++ ++MODULE_AUTHOR("Intel Corporation"); ++MODULE_LICENSE("Dual BSD/GPL"); ++MODULE_DESCRIPTION("User Space DMA-able Memory Driver"); ++ ++ +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/kernel_space/qae_mem_drv_utils.c +@@ -0,0 +1,82 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++/** ++***************************************************************************** ++ * @file qae_mem_drv_utils.c ++ * ++ * This file handles ioctls from user space to kernel space for quick assist API ++ * ++ *****************************************************************************/ ++ ++#include ++#include ++#include ++ ++#include "qae_mem_utils.h" ++ ++int handle_other_ioctls(uint32_t cmd) ++{ ++ mm_err("Invalid IOCTL command specified(0x%x)\n", cmd); ++ return -EINVAL; ++} ++ +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/kernel_space/qae_mem_utils.c +@@ -0,0 +1,277 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++/** ++***************************************************************************** ++ * @file qae_mem_utils.c ++ * ++ * This file provides linux kernel memory allocation for quick assist API ++ * ++ *****************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "qae_mem.h" ++#include "qae_mem_utils.h" ++ ++#define IS_VMALLOC_ADDR(addr) (((uintptr_t)(addr) >= VMALLOC_START) && \ ++ ((uintptr_t)(addr) < VMALLOC_END)) ++ ++/** ++****************************************************************************** ++* @ingroup max_mem_numa ++* maximum amount of memory allocated in kernel space ++* @description ++* This is a command line parameter that defines the maximum ++* amount of memory allocated by the driver in kernel space. ++* Measured in kilobytes. ++*****************************************************************************/ ++static uint32_t max_mem_numa = 0; ++/** ++****************************************************************************** ++* @ingroup mem_allocated ++* amount of memory currently allocated in kernel space ++* @description ++* This variable holds the overall ++* amount of memory allocated by the driver in kernel space. ++* Measured in bytes. ++*****************************************************************************/ ++static size_t mem_allocated = 0; ++module_param(max_mem_numa, uint, S_IRUGO); ++MODULE_PARM_DESC(max_mem_numa,"Maximum number of allocatable memory in 1k units"); ++ ++static uint32_t numaAllocations_g = 0; ++static uint32_t normalAllocations_g = 0; ++ ++/*Defining Max Size limit to be used, to allocate using kmalloc as 4MB */ ++static const int QAE_MEM_SIZE_LIMIT = 1024 * 4096; ++ ++/************************************** ++ * Memory functions ++ *************************************/ ++void* qaeMemAlloc (size_t memsize) ++{ ++ if(memsize > QAE_MEM_SIZE_LIMIT) ++ { ++ return ( vmalloc(memsize) ); ++ } ++ normalAllocations_g++; ++ return (kmalloc (memsize, GFP_KERNEL)); ++} ++ ++void* qaeMemAllocNUMA(size_t size, int node, size_t alignment) ++{ ++ void* ptr = NULL; ++ void* phys_ptr = NULL; ++ void* pRet = NULL; ++ size_t alignment_offset = 0; ++ qae_mem_alloc_info_t memInfo = {0}; ++ size_t totalInKBytes = (mem_allocated + size)/QAE_KBYTE; ++ ++ if( (mem_allocated + size) % QAE_KBYTE ) ++ { ++ totalInKBytes += 1; ++ } ++ ++ if( max_mem_numa && max_mem_numa < totalInKBytes) ++ { ++ mm_err("%s:%d Maximum NUMA allocation of %u kB reached " ++ "currently allocated %zu bytes requested %zu bytes\n", ++ __func__,__LINE__,max_mem_numa,mem_allocated, size); ++ return NULL; ++ } ++ ++ if(!size || alignment < 1) ++ { ++ mm_err("%s:%d Either size or alignment is zero - size = %zu, " ++ "alignment = %zu \n",__func__,__LINE__,size,alignment); ++ return NULL; ++ } ++ /*alignment should be 1,2,4,8....*/ ++ if(alignment & (alignment-1)) ++ { ++ mm_err("%s:%d Expecting alignment of a power of "\ ++ "two but did not get one\n",__func__,__LINE__); ++ return NULL; ++ } ++ /*add the alignment and the struct size to the buffer size*/ ++ memInfo.mSize = icp_iommu_get_remapping_size(size + alignment + ++ sizeof(qae_mem_alloc_info_t)); ++ if(memInfo.mSize > QAE_MEM_SIZE_LIMIT) ++ { ++ mm_err("%s:%d Total size needed for this " \ ++ "set of size and alignment (%zu) exceeds the OS " \ ++ "limit %d\n", __func__,__LINE__,memInfo.mSize,QAE_MEM_SIZE_LIMIT); ++ return NULL; ++ } ++ /*allocate contigous memory*/ ++ ptr = kmalloc_node (memInfo.mSize, GFP_KERNEL, node); ++ if(!ptr) ++ { ++ mm_err("%s:%d failed to allocate memory\n",__func__,__LINE__); ++ return NULL; ++ } ++ /*store the base address into the struct*/ ++ memInfo.mAllocMemPtr = ptr; ++#ifdef ICP_IOMMU_DISABLED ++ icp_iommu_map(&phys_ptr, ptr, memInfo.mSize); ++#else ++ if (icp_iommu_map(&phys_ptr, ptr, memInfo.mSize)) ++ { ++ mm_err("%s:%d failed to iommu map\n",__func__,__LINE__); ++ kfree(ptr); ++ return NULL; ++ } ++#endif ++ /*add the size of the struct to the return pointer*/ ++ pRet = (char *)memInfo.mAllocMemPtr + sizeof(qae_mem_alloc_info_t); ++ /*compute the offset from the alignement*/ ++ alignment_offset = (uintptr_t)pRet % alignment; ++ /*in order to obtain the pointer to the buffer add the alignment and ++ subtract the offset, now we have the return pointer aligned*/ ++ pRet = (char*)pRet + (alignment - alignment_offset); ++ /*copy the struct immediately before the buffer pointer*/ ++ memcpy((void*)((char*)pRet - sizeof(qae_mem_alloc_info_t)), ++ (void*)(&memInfo), ++ sizeof(qae_mem_alloc_info_t)); ++ /*increment the NUMA allocations counter*/ ++ numaAllocations_g++; ++ mem_allocated += memInfo.mSize; ++ return pRet; ++} ++ ++void qaeMemFreeNUMA (void** ptr) ++{ ++ qae_mem_alloc_info_t *memInfo = NULL; ++ uint64_t phy_addr = 0; ++ ++ if(!ptr || !(*ptr) ) ++ { ++ mm_err("%s:%d Pointer to be freed cannot be NULL\n", ++ __func__,__LINE__); ++ return; ++ } ++ memInfo = (qae_mem_alloc_info_t *)((int8_t *)*ptr - ++ sizeof(qae_mem_alloc_info_t)); ++ ++ if (memInfo->mSize == 0 || memInfo->mAllocMemPtr == NULL) ++ { ++ mm_err("%s:%d Detected the corrupted data: memory leak!! \n", ++ __func__,__LINE__); ++ mm_err("%s:%d Size: %zu, memPtr: %p\n", ++ __func__,__LINE__,memInfo->mSize, memInfo->mAllocMemPtr); ++ return; ++ } ++ phy_addr = virt_to_phys(memInfo->mAllocMemPtr); ++#ifdef ICP_IOMMU_DISABLED ++ icp_iommu_unmap((void*)(uintptr_t) phy_addr, memInfo->mSize); ++#else ++ if (icp_iommu_unmap((void*)(uintptr_t) phy_addr, memInfo->mSize)) ++ { ++ mm_warning("%s:%d failed to iommu unmap\n",__func__,__LINE__); ++ } ++#endif ++ kfree (memInfo->mAllocMemPtr); ++ numaAllocations_g--; ++ if ( mem_allocated > memInfo->mSize ) ++ { ++ mem_allocated -= memInfo->mSize; ++ } ++ else ++ { ++ mem_allocated = 0; ++ } ++ *ptr = NULL; ++} ++ ++void qaeMemFree (void **ptr) ++{ ++ if(!ptr || !(*ptr) ) ++ { ++ mm_err("%s:%d Pointer to be freed cannot be NULL\n",__func__,__LINE__); ++ return; ++ } ++ if(IS_VMALLOC_ADDR(*ptr)) ++ { ++ vfree(*ptr); ++ return; ++ } ++ kfree (*ptr); ++ normalAllocations_g--; ++ *ptr = NULL; ++} ++ ++uint64_t qaeVirtToPhysNUMA(void* ptr) ++{ ++ if (!ptr) ++ { ++ mm_err("%s:%d Input parameter cannot be NULL \n", ++ __func__,__LINE__); ++ return 0; ++ } ++ return (uint64_t)(uintptr_t)virt_to_phys(ptr); ++} +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/kernel_space/qdm.c +@@ -0,0 +1,187 @@ ++/* ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * Copyright(c) 2016 Intel Corporation. ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * Contact Information: ++ * ++ * qat-linux@intel.com ++ * ++ * BSD LICENSE ++ * Copyright(c) 2016 Intel Corporation. ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++#ifndef LINUX_VERSION_CODE ++#include ++#else ++#define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) ++#endif ++ ++#include ++#include ++#include ++#include "qdm.h" ++ ++static struct iommu_domain *domain; ++ ++/** ++ * qdm_attach_device() - Attach a device to the QAT IOMMU domain ++ * @dev: Device to be attached ++ * ++ * Function attaches the device to the QDM IOMMU domain. ++ * ++ * Return: 0 on success, error code otherwise. ++ */ ++int qdm_attach_device(struct device *dev) ++{ ++ if (!domain) ++ return 0; ++ ++ if (!dev) { ++ pr_err("QDM: Invalid device\n"); ++ return -ENODEV; ++ } ++ ++ return iommu_attach_device(domain, dev); ++} ++ ++/** ++ * qdm_detach_device() - Detach a device from the QAT IOMMU domain ++ * @dev: Device to be detached ++ * ++ * Function detaches the device from the QDM IOMMU domain. ++ * ++ * Return: 0 on success, error code otherwise. ++ */ ++int qdm_detach_device(struct device *dev) ++{ ++ if (!domain) ++ return 0; ++ ++ if (!dev) { ++ pr_err("QDM: Invalid device\n"); ++ return -ENODEV; ++ } ++ ++ iommu_detach_device(domain, dev); ++ return 0; ++} ++ ++/** ++ * qdm_iommu_map() - Map a block of memory to the QAT IOMMU domain ++ * @iova: Device virtual address ++ * @vaddr: Kernel virtual address ++ * @size: Size (in bytes) of the memory block. ++ * Must be a multiple of PAGE_SIZE ++ * ++ * Function maps a block of memory to the QDM IOMMU domain. ++ * ++ * Return: 0 on success, error code otherwise. ++ */ ++int qdm_iommu_map(dma_addr_t *iova, void *vaddr, size_t size) ++{ ++ phys_addr_t paddr = (phys_addr_t) virt_to_phys(vaddr); ++ *iova = (dma_addr_t) paddr; ++ ++ if (!domain) ++ return 0; ++ ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34) ++ return iommu_map_range(domain, *iova, paddr, size, ++ IOMMU_READ|IOMMU_WRITE|IOMMU_CACHE); ++#elif LINUX_VERSION_CODE <= KERNEL_VERSION(3,2,45) && \ ++ LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) ++ return iommu_map(domain, *iova, paddr, get_order(size), ++ IOMMU_READ|IOMMU_WRITE|IOMMU_CACHE); ++#else ++ return iommu_map(domain, *iova, paddr, size, ++ IOMMU_READ|IOMMU_WRITE|IOMMU_CACHE); ++#endif ++} ++EXPORT_SYMBOL_GPL(qdm_iommu_map); ++ ++/** ++ * qdm_iommu_unmap() - Unmap a block of memory from the QAT IOMMU domain ++ * @iova: Device virtual address ++ * @size: Size (in bytes) of the memory block ++ * Must be the same size as mapped. ++ * ++ * Function unmaps a block of memory from the QDM IOMMU domain. ++ * ++ * Return: 0 on success, error code otherwise. ++ */ ++int qdm_iommu_unmap(dma_addr_t iova, size_t size) ++{ ++ if (!domain) ++ return 0; ++ ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34) ++ iommu_unmap_range(domain, (unsigned long)iova, size); ++#elif LINUX_VERSION_CODE <= KERNEL_VERSION(3,2,45) && \ ++ LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) ++ iommu_unmap(domain, (unsigned long)iova, get_order(size)); ++#else ++ iommu_unmap(domain, (unsigned long)iova, size); ++#endif ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(qdm_iommu_unmap); ++ ++int __init qdm_init(void) ++{ ++ if (!iommu_present(&pci_bus_type)) ++ return 0; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) ++ domain = iommu_domain_alloc(); ++#else ++ domain = iommu_domain_alloc(&pci_bus_type); ++#endif ++ if (!domain) { ++ pr_err("QDM: Failed to allocate a domain\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++void __exit qdm_exit(void) ++{ ++ if (domain) ++ iommu_domain_free(domain); ++ domain = NULL; ++} +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/user_space/qae_mem_hugepage_utils.c +@@ -0,0 +1,288 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++/** ++ **************************************************************************** ++ * @file qae_mem_hugepage_utils.c ++ * ++ * This file provides for utilities for Linux/FreeBSD user space memory ++ * allocation with huge page enabled. ++ * ++ ***************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifndef __FreeBSD__ ++#include "qae_page_table.h" ++#endif ++#include "qae_mem_hugepage_utils.h" ++#include "qae_mem_user_utils.h" ++ ++#define HUGEPAGE_FILE_DIR "/dev/hugepages/usdm.XXXXXX" ++#define HUGEPAGE_FILE_LEN (sizeof(HUGEPAGE_FILE_DIR)) ++ ++#ifndef __FreeBSD__ ++static bool g_hugepages_enabled = false; ++#else ++static const bool g_hugepages_enabled = false; ++#endif ++ ++static size_t g_num_hugepages = 0; ++ ++#ifndef __FreeBSD__ /* FreeBSD only uses init_hugepages, hugepage_enabled */ ++/* ++ * Get physical address of mapped hugepage virtual address in the current ++ * process. ++ */ ++API_LOCAL ++uint64_t hugepage_virt2phy(const int fd, const void *virtaddr) ++{ ++ int ret = 0; ++ user_page_info_t user_pages = {0}; ++ ++ user_pages.virt_addr = (uintptr_t)virtaddr; ++ ret = mem_ioctl(fd, DEV_MEM_IOC_GET_USER_PAGE, &user_pages); ++ if (ret) ++ { ++ CMD_ERROR("%s:%d ioctl call for get physical addr failed, " ++ "ret = %d\n", ++ __func__, ++ __LINE__, ++ ret); ++ ret = -EIO; ++ } ++ ++ return user_pages.phy_addr; ++} ++ ++API_LOCAL ++void *hugepage_mmap_phy_addr(const size_t len) ++{ ++ void *addr = NULL; ++ int ret = 0; ++ int hpg_fd; ++ char hpg_fname[HUGEPAGE_FILE_LEN]; ++ ++ /* ++ * for every mapped huge page there will be a separate file descriptor ++ * created from a temporary file, we should NOT close fd explicitly, it ++ * will be reclaimed by the OS when the process gets terminated, and ++ * meanwhile the huge page binding to the fd will be released, this could ++ * guarantee the memory cleanup order between user buffers and ETR. ++ */ ++ snprintf(hpg_fname, sizeof(HUGEPAGE_FILE_DIR), "%s", HUGEPAGE_FILE_DIR); ++ hpg_fd = qae_mkstemp(hpg_fname); ++ ++ if (hpg_fd < 0) ++ { ++ CMD_ERROR("%s:%d mkstemp(%s) for hpg_fd failed with errno: %d\n", ++ __func__, ++ __LINE__, ++ hpg_fname, ++ errno); ++ return NULL; ++ } ++ ++ unlink(hpg_fname); ++ ++ addr = qae_mmap(NULL, ++ len, ++ PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | MAP_HUGETLB, ++ hpg_fd, ++ 0); ++ ++ if (MAP_FAILED == addr) ++ { ++ CMD_ERROR("%s:%d qae_mmap(%s) for hpg_fd failed with errno:%d\n", ++ __func__, ++ __LINE__, ++ hpg_fname, ++ errno); ++ close(hpg_fd); ++ return NULL; ++ } ++ ++ ret = qae_madvise(addr, len, MADV_DONTFORK); ++ if (0 != ret) ++ { ++ munmap(addr, len); ++ CMD_ERROR("%s:%d qae_madvise(%s) for hpg_fd failed with errno:%d\n", ++ __func__, ++ __LINE__, ++ hpg_fname, ++ errno); ++ close(hpg_fd); ++ return NULL; ++ } ++ ++ ((dev_mem_info_t *)addr)->hpg_fd = hpg_fd; ++ return addr; ++} ++ ++API_LOCAL ++dev_mem_info_t *hugepage_alloc_slab(const int fd, ++ const size_t size, ++ const int node, ++ enum slabType type) ++{ ++ dev_mem_info_t *slab = NULL; ++ ++ if (!g_num_hugepages) ++ { ++ CMD_ERROR("%s:%d mmap: exceeded max huge pages allocations for this " ++ "process.\n", ++ __func__, ++ __LINE__); ++ return NULL; ++ } ++ slab = hugepage_mmap_phy_addr(size); ++ if (!slab) ++ { ++ CMD_ERROR("%s:%d mmap on huge page memory allocation failed\n", ++ __func__, ++ __LINE__); ++ return NULL; ++ } ++ slab->nodeId = node; ++ slab->size = size; ++ slab->type = type; ++ slab->virt_addr = slab; ++ slab->phy_addr = hugepage_virt2phy(fd, slab); ++ if (!slab->phy_addr) ++ { ++ CMD_ERROR("%s:%d virt2phy on huge page memory allocation failed\n", ++ __func__, ++ __LINE__); ++ close(slab->hpg_fd); ++ munmap(slab, size); ++ return NULL; ++ } ++ g_num_hugepages--; ++ ++ return slab; ++} ++ ++API_LOCAL ++void hugepage_free_slab(const dev_mem_info_t *memInfo) ++{ ++ g_num_hugepages++; ++ ++ close(memInfo->hpg_fd); ++} ++ ++#endif /* !__FreeBSD__ */ ++ ++API_LOCAL ++int init_hugepages(const int fd) ++{ ++ int ret = 0; ++#if (QAE_NUM_PAGES_PER_ALLOC == 512) ++#ifndef __FreeBSD__ ++ ret = mem_ioctl(fd, DEV_MEM_IOC_GET_NUM_HPT, &g_num_hugepages); ++ if (ret) ++ { ++ CMD_ERROR("%s:%d ioctl call for checking number of huge page failed, " ++ "ret = %d\n", ++ __func__, ++ __LINE__, ++ ret); ++ g_num_hugepages = 0; ++ ret = -EIO; ++ } ++ if (g_num_hugepages > 0) ++ { ++ set_free_page_table_fptr(free_page_table_hpg); ++ set_loadaddr_fptr(load_addr_hpg); ++ set_loadkey_fptr(load_key_hpg); ++ ++ g_hugepages_enabled = true; ++ } ++ else ++ { ++ set_free_page_table_fptr(free_page_table); ++ set_loadaddr_fptr(load_addr); ++ set_loadkey_fptr(load_key); ++ ++ g_hugepages_enabled = false; ++ } ++#endif /* !__FreeBSD__ */ ++#else ++ if (fd < 0) ++ return -EIO; ++#endif ++ return ret; ++} ++ ++API_LOCAL ++int hugepage_enabled() ++{ ++ return g_hugepages_enabled; ++} +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/user_space/qae_mem_hugepage_utils.h +@@ -0,0 +1,91 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++/** ++ **************************************************************************** ++ * @file qae_mem_hugepage_utils.h ++ * ++ * This file provides API for utilities of Linux/FreeBSD user space memory ++ * allocation with huge page enabled. ++ * ++ ***************************************************************************/ ++#ifndef QAE_MEM_HUGEPAGE_UTILS_H ++#define QAE_MEM_HUGEPAGE_UTILS_H ++#ifndef __FreeBSD__ ++#include "qae_mem_utils.h" ++ ++uint64_t hugepage_virt2phy(const int fd, const void *virtaddr); ++ ++void *hugepage_mmap_phy_addr(const size_t len); ++ ++dev_mem_info_t *hugepage_alloc_slab(const int fd, ++ const size_t size, ++ const int node, ++ enum slabType type); ++ ++void hugepage_free_slab(const dev_mem_info_t *memInfo); ++#endif /* !__FreeBSD__ */ ++ ++int init_hugepages(const int fd); ++ ++int hugepage_enabled(); ++#endif +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/user_space/qae_mem_user_utils.h +@@ -0,0 +1,108 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++/** ++ **************************************************************************** ++ * @file qae_mem_user_utils.h ++ * ++ * This file provides for API of Linux user space memory allocation ++ * ++ ***************************************************************************/ ++ ++#ifndef QAE_MEM_USER_UTILS_H ++#define QAE_MEM_USER_UTILS_H ++ ++#ifndef SKIP_BUILTIN_FUNC ++#define unlikely(x) __builtin_expect((x), 0) ++#else ++#define unlikely(x) (0 == (x)) ++#endif ++ ++#if __GNUC__ >= 4 ++#define API_PUBLIC __attribute__((visibility("default"))) ++#define API_LOCAL __attribute__((visibility("hidden"))) ++#else ++#define API_PUBLIC ++#define API_LOCAL ++#endif ++ ++#ifdef ICP_DEBUG ++static inline void CMD_DEBUG(const char *format, ...) ++{ ++ va_list args; ++ va_start(args, format); ++ vfprintf(stdout, format, args); ++ va_end(args); ++} ++#else ++#define CMD_DEBUG(...) ++#endif ++ ++static inline void CMD_ERROR(const char *format, ...) ++{ ++ va_list args; ++ va_start(args, format); ++ vfprintf(stderr, format, args); ++ va_end(args); ++} ++ ++#endif +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/user_space/qae_mem_utils.c +@@ -0,0 +1,1331 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++/** ++ **************************************************************************** ++ * @file qae_mem_utils.c ++ * ++ * This file provides for Linux user space memory allocation. It uses ++ * a driver that allocates the memory in kernel memory space (to ensure ++ * physically contiguous memory) and maps it to ++ * user space for use by the quick assist sample code ++ * ++ ***************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifndef ICP_WITHOUT_THREAD ++#include ++#endif ++#include ++#include ++#include ++#include "qae_mem.h" ++#include "qae_mem_utils.h" ++#include "qae_mem_user_utils.h" ++#include "qae_page_table.h" ++#include "qae_mem_hugepage_utils.h" ++ ++STATIC int fd = -1; ++ ++/************************************************************************** ++ macro ++**************************************************************************/ ++ ++#define QAE_MEM "/dev/usdm_drv" ++ ++/************************************************************************** ++ static variable ++**************************************************************************/ ++ ++/* Current cached memory size. */ ++static size_t g_cache_size = 0; ++/* Maximum cached memory size, 8 Mb by default */ ++static size_t g_max_cache = 0x800000; ++/* The maximum number we allow to search for available size */ ++static size_t g_max_lookup_num = 10; ++/* User space page table for fast virtual to physical address translation */ ++static page_table_t g_page_table = {{{0}}}; ++ ++typedef struct ++{ ++ dev_mem_info_t *head; ++ dev_mem_info_t *tail; ++} slab_list_t; ++/* User space hash for fast slab searching */ ++static slab_list_t g_slab_list[PAGE_SIZE] = {{0}}; ++ ++static int g_strict_node = 1; ++ ++#ifndef ICP_WITHOUT_THREAD ++static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ++#endif ++ ++static dev_mem_info_t *pUserCacheHead = NULL; ++static dev_mem_info_t *pUserCacheTail = NULL; ++static dev_mem_info_t *pUserMemListHead = NULL; ++static dev_mem_info_t *pUserMemListTail = NULL; ++static dev_mem_info_t *pUserLargeMemListHead = NULL; ++static dev_mem_info_t *pUserLargeMemListTail = NULL; ++ ++ ++static free_page_table_fptr_t free_page_table_fptr = free_page_table; ++static load_addr_fptr_t load_addr_fptr = load_addr; ++static load_key_fptr_t load_key_fptr = load_key; ++ ++/************************************************************************** ++ function ++**************************************************************************/ ++#ifndef __FreeBSD__ ++API_LOCAL ++void set_free_page_table_fptr(free_page_table_fptr_t fp) ++{ ++ free_page_table_fptr = fp; ++} ++ ++API_LOCAL ++void set_loadaddr_fptr(load_addr_fptr_t fp) ++{ ++ load_addr_fptr = fp; ++} ++ ++API_LOCAL ++void set_loadkey_fptr(load_key_fptr_t fp) ++{ ++ load_key_fptr = fp; ++} ++#endif /* __FreeBSD__ */ ++ ++static inline size_t div_round_up(const size_t n, const size_t d) ++{ ++ return (n + d - 1) / d; ++} ++ ++static inline void add_slab_to_hash(dev_mem_info_t *slab) ++{ ++ const size_t key = get_key(slab->phy_addr); ++ ++ ADD_ELEMENT_TO_HEAD_LIST( ++ slab, g_slab_list[key].head, g_slab_list[key].tail, _user_hash); ++} ++static inline void del_slab_from_hash(dev_mem_info_t *slab) ++{ ++ const size_t key = get_key(slab->phy_addr); ++ ++ REMOVE_ELEMENT_FROM_LIST( ++ slab, g_slab_list[key].head, g_slab_list[key].tail, _user_hash); ++} ++ ++static inline dev_mem_info_t *find_slab_in_hash(void *virt_addr) ++{ ++ const size_t key = load_key_fptr(&g_page_table, virt_addr); ++ dev_mem_info_t *slab = g_slab_list[key].head; ++ ++ while (slab) ++ { ++ uintptr_t offs = (uintptr_t)virt_addr - (uintptr_t)slab->virt_addr; ++ if (offs < slab->size) ++ return slab; ++ slab = slab->pNext_user_hash; ++ } ++ ++ return NULL; ++} ++ ++/* mem_ctzll function ++ * input: a 64-bit bitmap window ++ * output: number of contiguous 0s from least significant bit position ++ * __GNUC__ predefined macro and __builtin_ctz() are supported by Intel C ++ */ ++static inline int32_t mem_ctzll(uint64_t bitmap_window) ++{ ++ if (bitmap_window) ++ { ++#ifdef __GNUC__ ++ return __builtin_ctzll(bitmap_window); ++#else ++#error "Undefined built-in function" ++#endif ++ } ++ return QWORD_WIDTH; ++} ++ ++/* bitmap_read function ++ * reads a 64-bit window from a BITMAP_LENx64-bit bitmap ++ * starting from window_pos (0 <-> BITMAP_LENx64 -1) ++ * map points to the BITMAP_LENx64 bit map area ++ * returns the 64-bit window from the BITMAP_LENx64 bitmap. ++ * Each bit represents a 1k block in the 2 Meg buffer ++ */ ++ ++static uint64_t bitmap_read(uint64_t *map, size_t window_pos) ++{ ++ uint64_t quad_word_window = 0ULL; ++ uint64_t next_quad_word = 0ULL; ++ size_t quad_word_pos = 0; ++ size_t bit_pos = 0; ++ ++ quad_word_pos = window_pos / QWORD_WIDTH; ++ ++ if (quad_word_pos >= BITMAP_LEN) ++ { ++ return QWORD_ALL_ONE; ++ } ++ bit_pos = window_pos % QWORD_WIDTH; ++ ++ quad_word_window = map[quad_word_pos]; ++ ++ if (0 == bit_pos) ++ { ++ return quad_word_window; ++ } ++ ++ /* it is safe to read the next quad word because ++ * there is always a barrier at the end */ ++ next_quad_word = map[quad_word_pos + 1]; ++ ++ quad_word_window >>= bit_pos; ++ next_quad_word <<= QWORD_WIDTH - bit_pos; ++ quad_word_window |= next_quad_word; ++ ++ return quad_word_window; ++} ++ ++static const uint64_t __bitmask[65] = { ++ 0x0000000000000000ULL, 0x0000000000000001ULL, 0x0000000000000003ULL, ++ 0x0000000000000007ULL, 0x000000000000000fULL, 0x000000000000001fULL, ++ 0x000000000000003fULL, 0x000000000000007fULL, 0x00000000000000ffULL, ++ 0x00000000000001ffULL, 0x00000000000003ffULL, 0x00000000000007ffULL, ++ 0x0000000000000fffULL, 0x0000000000001fffULL, 0x0000000000003fffULL, ++ 0x0000000000007fffULL, 0x000000000000ffffULL, 0x000000000001ffffULL, ++ 0x000000000003ffffULL, 0x000000000007ffffULL, 0x00000000000fffffULL, ++ 0x00000000001fffffULL, 0x00000000003fffffULL, 0x00000000007fffffULL, ++ 0x0000000000ffffffULL, 0x0000000001ffffffULL, 0x0000000003ffffffULL, ++ 0x0000000007ffffffULL, 0x000000000fffffffULL, 0x000000001fffffffULL, ++ 0x000000003fffffffULL, 0x000000007fffffffULL, 0x00000000ffffffffULL, ++ 0x00000001ffffffffULL, 0x00000003ffffffffULL, 0x00000007ffffffffULL, ++ 0x0000000fffffffffULL, 0x0000001fffffffffULL, 0x0000003fffffffffULL, ++ 0x0000007fffffffffULL, 0x000000ffffffffffULL, 0x000001ffffffffffULL, ++ 0x000003ffffffffffULL, 0x000007ffffffffffULL, 0x00000fffffffffffULL, ++ 0x00001fffffffffffULL, 0x00003fffffffffffULL, 0x00007fffffffffffULL, ++ 0x0000ffffffffffffULL, 0x0001ffffffffffffULL, 0x0003ffffffffffffULL, ++ 0x0007ffffffffffffULL, 0x000fffffffffffffULL, 0x001fffffffffffffULL, ++ 0x003fffffffffffffULL, 0x007fffffffffffffULL, 0x00ffffffffffffffULL, ++ 0x01ffffffffffffffULL, 0x03ffffffffffffffULL, 0x07ffffffffffffffULL, ++ 0x0fffffffffffffffULL, 0x1fffffffffffffffULL, 0x3fffffffffffffffULL, ++ 0x7fffffffffffffffULL, 0xffffffffffffffffULL, ++}; ++ ++/* clear_bitmap function ++ * clear the BITMAP_LENx64-bit bitmap from pos ++ * for len length ++ * input : map - pointer to the bitmap ++ * pos - bit position ++ * len - number of contiguous bits ++ */ ++static inline void clear_bitmap(uint64_t *bitmap, ++ const size_t index, ++ size_t len) ++{ ++ size_t qword = index / QWORD_WIDTH; ++ const size_t offset = index % QWORD_WIDTH; ++ size_t num; ++ ++ if (offset > 0) ++ { ++ const size_t width = MIN(len, QWORD_WIDTH - offset); ++ const uint64_t mask = __bitmask[width] << offset; ++ ++ /* Clear required bits */ ++ bitmap[qword] &= ~mask; ++ ++ len -= width; ++ qword += 1; ++ } ++ ++ num = len / QWORD_WIDTH; ++ len %= QWORD_WIDTH; ++ ++ while (num--) ++ { ++ bitmap[qword++] = 0; ++ } ++ ++ /* Clear remaining bits */ ++ bitmap[qword] &= ~__bitmask[len]; ++} ++ ++/* set_bitmap function ++ * set the BITMAP_LENx64-bit bitmap from pos ++ * for len length ++ * input : map - pointer to the bitmap ++ * pos - bit position ++ * len - number of contiguous bits ++ */ ++static inline void set_bitmap(uint64_t *bitmap, const size_t index, size_t len) ++{ ++ size_t qword = index / QWORD_WIDTH; ++ const size_t offset = index % QWORD_WIDTH; ++ size_t num; ++ ++ if (offset > 0) ++ { ++ const size_t width = MIN(len, QWORD_WIDTH - offset); ++ const uint64_t mask = __bitmask[width] << offset; ++ ++ /* Set required bits */ ++ bitmap[qword] |= mask; ++ ++ len -= width; ++ qword += 1; ++ } ++ ++ num = len / QWORD_WIDTH; ++ len %= QWORD_WIDTH; ++ ++ while (num--) ++ { ++ bitmap[qword++] = ~0ULL; ++ } ++ ++ /* Set remaining bits */ ++ bitmap[qword] |= __bitmask[len]; ++} ++ ++/* mem_alloc function ++ * mem_alloc allocates memory with min. size = UNIT_SIZE ++ * block_ctrl points to a block_ctrl_t structure with virtual address ++ * size is the requested number of bytes ++ * minimum allocation size is UNIT_SIZE ++ * returns a pointer to the newly allocated block ++ * input: block_ctrl - pointer to the memory control block ++ * size - size requested in bytes ++ * output: pointer to the allocated area ++ */ ++static void *mem_alloc(block_ctrl_t *block_ctrl, size_t size, size_t align) ++{ ++ uint64_t *bitmap = NULL; ++ size_t window_pos = 0; ++ void *retval = NULL; ++ size_t blocks_found = 0; ++ uint64_t bitmap_window = 0ULL; ++ size_t blocks_required = 0ULL; ++ size_t first_block = 0; ++ size_t width = 0; ++ size_t width_ones = 0; ++ ++ if (NULL == block_ctrl || 0 == size) ++ { ++ CMD_ERROR(" %s:%d invalid control block or size provided " ++ "block_ctrl = %p and size = %d \n", ++ __func__, ++ __LINE__, ++ block_ctrl, ++ size); ++ return retval; ++ } ++ ++ bitmap = block_ctrl->bitmap; ++ ++ blocks_required = div_round_up(size, UNIT_SIZE); ++ ++ window_pos = 0; ++ first_block = window_pos; ++ ++ do ++ { ++ /* read 64-bit bitmap window from window_pos (0-BITMAP_LEN*64) */ ++ bitmap_window = bitmap_read(bitmap, window_pos); ++ /* find number of contiguous 0s from right */ ++ width = mem_ctzll(bitmap_window); ++ ++ /* increment number of blocks found with number of contig. 0s ++ in bitmap window */ ++ blocks_found += width; ++ /* check if a fit is found */ ++ if (blocks_found >= blocks_required) ++ { ++ /* calculate return address from virtual address and ++ first block number */ ++ retval = (uint8_t *)(block_ctrl) + first_block * UNIT_SIZE; ++ if (first_block + blocks_required > BITMAP_LEN * QWORD_WIDTH) ++ { ++ CMD_ERROR("%s:%d Allocation error - Required blocks exceeds " ++ "bitmap window. Block index = %d, Blocks required" ++ " = %zu and Bitmap window = %d \n", ++ __func__, ++ __LINE__, ++ first_block, ++ blocks_required, ++ (BITMAP_LEN * QWORD_WIDTH)); ++ return NULL; ++ } ++ /* save length in the reserved area right after the bitmap */ ++ block_ctrl->sizes[first_block] = (uint16_t)blocks_required; ++ /* set bit maps from bit position (0<->BITMAP_LEN*64 -1) = ++ * first_block(0<->BITMAP_LEN*64-1) ++ * with blocks_required length in bitmap ++ */ ++ set_bitmap(bitmap, first_block, blocks_required); ++ break; ++ } ++ else ++ { ++ /* did not find fit check if bitmap_window has at least a 1*/ ++ if (bitmap_window) ++ { ++ /* bit field of 0s not contiguous, clear blocks_found adjust ++ * first_block and window_pos find width of contiguous 1 bits ++ * and move window position will read next 64-bit wide window ++ * from bitmap ++ */ ++ bitmap_window >>= (width + 1); ++ width_ones = mem_ctzll(~bitmap_window); ++ blocks_found = 0; ++ window_pos += width + 1 + width_ones; ++ if (align && window_pos % align) ++ { ++ window_pos += align - window_pos % align; ++ } ++ first_block = window_pos; ++ } ++ else ++ { ++ /* bit field of 0s is contiguous, but fit not found yet ++ * move window_pos an search more 0s */ ++ window_pos += width; ++ } ++ } ++ } while (window_pos < BITMAP_LEN * QWORD_WIDTH); ++ return retval; ++} ++/* ++ * deallocates previously allocated blocks ++ * block_ctrl is a pointer to block_ctrl_t structure ++ * block is a result from a previous mem_alloc call ++ */ ++static void mem_free(block_ctrl_t *block_ctrl, void *block) ++{ ++ size_t first_block = 0; ++ uint32_t length = 0; ++ uint8_t *start_of_block = block; ++ uint64_t *bitmap = NULL; ++ ++ if (NULL == block_ctrl || NULL == block) ++ { ++ CMD_ERROR("%s:%d One of the parameters is NULL. block_ctrl = %p " ++ "block = %p\n", ++ __func__, ++ __LINE__, ++ block_ctrl, ++ block); ++ return; ++ } ++ ++ if ((uintptr_t)block % UNIT_SIZE) ++ { ++ CMD_ERROR("%s:%d Block address(%p) must be multiple of Unit size(%d)\n", ++ __func__, ++ __LINE__, ++ block, ++ UNIT_SIZE); ++ return; ++ } ++ ++ bitmap = block_ctrl->bitmap; ++ ++ /* find start of block in block numbers using the address of start of ++ * buffer and block retrieve first_block and length of block from integer ++ * at the start of block ++ */ ++ first_block = ++ (uintptr_t)(start_of_block - (uint8_t *)(block_ctrl)) / UNIT_SIZE; ++ ++ length = block_ctrl->sizes[first_block]; ++ ++ if (length + first_block > BITMAP_LEN * QWORD_WIDTH) ++ { ++ CMD_ERROR("%s:%d Invalid block address provided - " ++ "block length exceeds bitmap window. block index = %d " ++ "and block length: %d\n", ++ __func__, ++ __LINE__, ++ first_block, ++ length); ++ return; ++ } ++ /* clear bitmap from bitmap position (0<->BITMAP_LEN*64 - 1) for length*/ ++ clear_bitmap(bitmap, first_block, length); ++ ++#ifndef ICP_DISABLE_SECURE_MEM_FREE ++ qae_memzero_explicit(block, length * UNIT_SIZE); ++#endif ++} ++ ++static dev_mem_info_t *userMemLookupBySize(size_t size, ++ int node, ++ void **block, ++ const size_t align) ++{ ++ dev_mem_info_t *pCurr = NULL; ++ size_t link_num = 0; ++ ++ for (pCurr = pUserMemListHead; pCurr != NULL; pCurr = pCurr->pNext_user) ++ { ++ if (g_strict_node && (pCurr->nodeId != node)) ++ { ++ continue; ++ } ++ *block = mem_alloc((block_ctrl_t *)pCurr, size, align); ++ if (NULL != *block) ++ { ++ return pCurr; ++ } ++ /* Prevent from visiting whole chain, because after the first ++ * several node, the chance to get one is very small. ++ * Another consideration is to prevent new allocation from old ++ * link, so that the old link could be released ++ */ ++ link_num++; ++ if (link_num >= g_max_lookup_num) ++ { ++ break; ++ } ++ } ++ return NULL; ++} ++ ++static inline void *init_slab_and_alloc(block_ctrl_t *slab, ++ const size_t size, ++ const size_t phys_align_unit) ++{ ++ const size_t last = slab->mem_info.size / CHUNK_SIZE; ++ dev_mem_info_t *p_ctrl_blk = &slab->mem_info; ++ const size_t reserved = div_round_up(sizeof(block_ctrl_t), UNIT_SIZE); ++ void *virt_addr = NULL; ++ ++ /* initialise the bitmap to 1 for reserved blocks */ ++ slab->bitmap[0] = (1ULL << reserved) - 1; ++ /* make a barrier to stop search at the end of the bitmap */ ++ slab->bitmap[last] = QWORD_ALL_ONE; ++ ++ virt_addr = mem_alloc(slab, size, phys_align_unit); ++ if (NULL != virt_addr) ++ { ++ ADD_ELEMENT_TO_HEAD_LIST( ++ p_ctrl_blk, pUserMemListHead, pUserMemListTail, _user); ++ } ++ return virt_addr; ++} ++ ++static inline int push_slab(dev_mem_info_t *slab) ++{ ++ if (g_cache_size + slab->size <= g_max_cache) ++ { ++ g_cache_size += slab->size; ++ ADD_ELEMENT_TO_HEAD_LIST(slab, pUserCacheHead, pUserCacheTail, _user); ++ return 0; ++ } ++ return -ENOMEM; ++} ++ ++static inline dev_mem_info_t *pop_slab(const int node) ++{ ++ dev_mem_info_t *slab = NULL; ++ ++ for (slab = pUserCacheHead; slab != NULL; slab = slab->pNext_user) ++ { ++ if (node != NUMA_ANY_NODE) ++ if (g_strict_node && (node != slab->nodeId)) ++ continue; ++ ++ g_cache_size -= slab->size; ++ REMOVE_ELEMENT_FROM_LIST(slab, pUserCacheHead, pUserCacheTail, _user); ++ return slab; ++ } ++ return NULL; ++} ++ ++static inline void free_slab(const int fd, dev_mem_info_t *slab) ++{ ++ dev_mem_info_t memInfo; ++ int ret = 0; ++ ++ del_slab_from_hash(slab); ++ ++ memcpy(&memInfo, slab, sizeof(dev_mem_info_t)); ++ /* Need to disconnect from orignal chain */ ++ ret = qae_munmap(memInfo.virt_addr, memInfo.size); ++ if (ret) ++ { ++ CMD_ERROR("%s:%d munmap failed, ret = %d\n", __func__, __LINE__, ret); ++ } ++ if (LARGE == memInfo.type) ++ { ++ ret = qae_munmap(slab, getpagesize()); ++ if (ret) ++ { ++ CMD_ERROR( ++ "%s:%d munmap failed, ret = %d\n", __func__, __LINE__, ret); ++ } ++ } ++ ++#ifndef __FreeBSD__ ++ if (HUGE_PAGE == memInfo.type) ++ { ++ hugepage_free_slab(&memInfo); ++ } ++ else ++#endif ++ { ++ ret = mem_ioctl(fd, DEV_MEM_IOC_MEMFREE, &memInfo); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR("%s:%d ioctl call for mem free failed, ret = %d\n", ++ __func__, ++ __LINE__, ++ ret); ++ } ++ } ++} ++ ++static inline dev_mem_info_t *find_slab(const int fd, ++ const size_t size, ++ const int node, ++ void **addr, ++ const size_t align) ++{ ++ dev_mem_info_t *slab = userMemLookupBySize(size, node, addr, align); ++ ++ if (NULL == slab) ++ { ++ slab = pop_slab(node); ++ if (NULL != slab) ++ { ++ *addr = init_slab_and_alloc((block_ctrl_t *)slab, size, align); ++ if (NULL == *addr) ++ { ++ CMD_ERROR("%s:%d Memory allocation failed Virtual address: %p " ++ " Size: %x \n", ++ __func__, ++ __LINE__, ++ slab, ++ size); ++ free_slab(fd, slab); ++ return NULL; ++ } ++ } ++ } ++ return slab; ++} ++ ++/************************************** ++ * Memory functions ++ *************************************/ ++void *qaeMemAlloc(size_t memsize) ++{ ++ void *memPtr = NULL; ++ memPtr = calloc(memsize, sizeof(uint8_t)); ++ return memPtr; ++} ++ ++void qaeMemFree(void **ptr) ++{ ++ if ((!ptr) || !(*ptr)) ++ { ++ CMD_ERROR("%s:%d Trying to Free NULL Pointer\n", __func__, __LINE__); ++ return; ++ } ++ free(*ptr); ++ *ptr = NULL; ++} ++ ++static inline int check_pid(void) ++{ ++ static pid_t pid = 0; ++ ++ if (pid != getpid()) ++ { ++ pid = getpid(); ++ return 1; ++ } ++ return 0; ++} ++ ++static inline int qaeOpenFd(void) ++{ ++ /* Check if it is a new process or child. */ ++ const int is_new_pid = check_pid(); ++ ++ if (fd < 0 || is_new_pid) ++ { ++ /* Reset all control structures. */ ++ free_page_table_fptr(&g_page_table); ++ memset(&g_page_table, 0, sizeof(g_page_table)); ++ memset(&g_slab_list, 0, sizeof(g_slab_list)); ++ g_cache_size = 0; ++ ++ pUserCacheHead = NULL; ++ pUserCacheTail = NULL; ++ pUserMemListHead = NULL; ++ pUserMemListTail = NULL; ++ pUserLargeMemListHead = NULL; ++ pUserLargeMemListTail = NULL; ++ ++ CMD_DEBUG("%s:%d Memory file handle is not initialized. " ++ "Initializing it now \n", ++ __func__, ++ __LINE__); ++ ++ if (fd > 0) ++ close(fd); ++ fd = qae_open(QAE_MEM, O_RDWR); ++ if (fd < 0) ++ { ++ CMD_ERROR("%s:%d Unable to initialize memory file handle %s \n", ++ __func__, ++ __LINE__, ++ QAE_MEM); ++ return -ENOENT; ++ } ++ ++ if (init_hugepages(fd)) ++ return -EIO; ++ } ++ return 0; ++} ++ ++int32_t qaeMemInit() ++{ ++ int32_t fd_status = 0; ++ int32_t status = 0; ++ ++ status = mem_mutex_lock(&mutex); ++ if (status) ++ { ++ CMD_ERROR("%s:%d Error on thread mutex lock %s\n", ++ __func__, ++ __LINE__, ++ strerror(status)); ++ return -EIO; ++ } ++ ++ fd_status = qaeOpenFd(); ++ ++ status = mem_mutex_unlock(&mutex); ++ if (status) ++ { ++ CMD_ERROR("%s:%d Error on thread mutex unlock %s\n", ++ __func__, ++ __LINE__, ++ strerror(status)); ++ return -EIO; ++ } ++ return fd_status; ++} ++ ++#ifdef __FreeBSD__ ++int qaeMemInitAndReturnFd(int *mem_fd) ++{ ++ int status = -1; ++ if (NULL != mem_fd) ++ { ++ status = qaeMemInit(); ++ } ++ if (status == 0) ++ { ++ *mem_fd = fd; ++ } ++ return status; ++} ++#endif /* __FreeBSD__ */ ++ ++static void destroyList(const int fd, dev_mem_info_t *pList) ++{ ++ dev_mem_info_t *pCurr = pList; ++ ++ while (pCurr) ++ { ++ dev_mem_info_t *next = pCurr->pNext_user; ++ free_slab(fd, pCurr); ++ pCurr = next; ++ } ++} ++ ++static inline void reset_cache(const int fd) ++{ ++ dev_mem_info_t *slab = NULL; ++ do ++ { ++ slab = pop_slab(NUMA_ANY_NODE); ++ if (NULL != slab) ++ free_slab(fd, slab); ++ } while (slab != NULL); ++} ++ ++void qaeMemDestroy(void) ++{ ++ int ret = 0; ++ ++ /* Free all of the chains */ ++ ret = mem_mutex_lock(&mutex); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR( ++ "%s:%d Error(%d) on thread mutex lock \n", __func__, __LINE__, ret); ++ return; ++ } ++ ++ /* release all control buffers */ ++ free_page_table_fptr(&g_page_table); ++ reset_cache(fd); ++ destroyList(fd, pUserMemListHead); ++ destroyList(fd, pUserLargeMemListHead); ++ ++ pUserCacheHead = NULL; ++ pUserCacheTail = NULL; ++ pUserMemListHead = NULL; ++ pUserMemListTail = NULL; ++ pUserLargeMemListHead = NULL; ++ pUserLargeMemListTail = NULL; ++ ++ /* Send ioctl to kernel space to remove block for this pid */ ++ if (fd > 0) ++ { ++ ret = mem_ioctl(fd, DEV_MEM_IOC_RELEASE, NULL); ++ if (ret) ++ { ++ CMD_ERROR("%s:%d ioctl call for mem release failed, ret = %d\n", ++ __func__, ++ __LINE__, ++ ret); ++ } ++ close(fd); ++ fd = -1; ++ } ++ ++ ret = mem_mutex_unlock(&mutex); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR("%s:%d Error(%d) on thread mutex unlock\n", ++ __func__, ++ __LINE__, ++ ret); ++ } ++} ++ ++#ifndef __FreeBSD__ ++static inline void *mem_protect(void *const addr, const size_t len) ++{ ++ int ret = 0; ++ ++ ret = qae_madvise(addr, len, MADV_DONTFORK); ++ if (0 != ret) ++ { ++ munmap(addr, len); ++ return NULL; ++ } ++ return addr; ++} ++#endif ++ ++static inline void *mmap_phy_addr(const int fd, ++ const uint64_t phy_addr, ++ const size_t len) ++{ ++ void *addr = NULL; ++ ++#ifdef __FreeBSD__ ++ addr = ++ qae_mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, phy_addr); ++ if (0 != mlock(addr, len)) ++ { ++ munmap(addr, len); ++ return NULL; ++ } ++#endif ++#ifndef __FreeBSD__ ++ addr = qae_mmap(NULL, ++ len, ++ PROT_READ | PROT_WRITE, ++ MAP_SHARED | MAP_LOCKED, ++ fd, ++ phy_addr); ++#endif ++ ++ if (MAP_FAILED == addr) ++ return NULL; ++ ++#ifndef __FreeBSD__ ++ addr = mem_protect(addr, len); ++#endif ++ ++ return addr; ++} ++ ++static inline dev_mem_info_t *ioctl_alloc_slab(const int fd, ++ const size_t size, ++ const int node, ++ enum slabType type) ++{ ++ dev_mem_info_t params = {0}; ++ int ret = 0; ++ dev_mem_info_t *slab = NULL; ++ ++ params.size = size; ++ params.nodeId = node; ++ params.type = type; ++ ++ ret = mem_ioctl(fd, DEV_MEM_IOC_MEMALLOC, ¶ms); ++ if (ret) ++ { ++ CMD_ERROR("%s:%d ioctl call for mem allocation failed, ret = %d\n", ++ __func__, ++ __LINE__, ++ ret); ++ return NULL; ++ } ++ ++ if (node != params.nodeId) ++ { ++ g_strict_node = 0; ++ } ++ ++ if (SMALL == type) ++ slab = mmap_phy_addr(fd, params.phy_addr, params.size); ++ else ++ slab = mmap_phy_addr(fd, params.phy_addr, getpagesize()); ++ ++ if (NULL == slab) ++ { ++ CMD_ERROR("%s:%d mmap on memory allocated through ioctl failed\n", ++ __func__, ++ __LINE__); ++ ret = mem_ioctl(fd, DEV_MEM_IOC_MEMFREE, ¶ms); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR("%s:%d ioctl call for mem free failed, ret = %d\n", ++ __func__, ++ __LINE__, ++ ret); ++ } ++ return NULL; ++ } ++ ++ if (SMALL == type) ++ slab->virt_addr = slab; ++ else ++ { ++ slab->virt_addr = mmap_phy_addr(fd, params.phy_addr, params.size); ++ ++ if (NULL == slab->virt_addr) ++ { ++ CMD_ERROR("%s:%d mmap failed for large memory allocation\n", ++ __func__, ++ __LINE__); ++ munmap(slab, getpagesize()); ++ ret = mem_ioctl(fd, DEV_MEM_IOC_MEMFREE, ¶ms); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR("%s:%d ioctl call for mem free failed, ret = %d\n", ++ __func__, ++ __LINE__, ++ ret); ++ } ++ return NULL; ++ } ++ } ++ ++ return slab; ++} ++ ++static inline dev_mem_info_t *alloc_slab(const int fd, ++ const size_t size, ++ const int node, ++ enum slabType type) ++{ ++ dev_mem_info_t *slab = NULL; ++ ++ if (HUGE_PAGE == type) ++ { ++#ifndef __FreeBSD__ ++ slab = hugepage_alloc_slab(fd, size, node, type); ++#endif ++ } ++ else ++ { ++ slab = ioctl_alloc_slab(fd, size, node, type); ++ } ++ ++ /* Store a slab into the hash table for a fast lookup. */ ++ if (slab) ++ add_slab_to_hash(slab); ++ ++ return slab; ++} ++ ++static inline void *alloc_addr(size_t size, ++ const int node, ++ const size_t phys_alignment_byte) ++{ ++ dev_mem_info_t *p_ctrl_blk = NULL; ++ void *pVirtAddress = NULL; ++ size_t allocate_pages = 0; ++ enum slabType mem_type = SMALL; ++ ++ const size_t phys_align_unit = phys_alignment_byte / UNIT_SIZE; ++ const size_t reserved = div_round_up(sizeof(block_ctrl_t), UNIT_SIZE); ++ /* calculate units needed */ ++ const size_t requested_pages = div_round_up(size, UNIT_SIZE) + reserved; ++ ++ if (0 != qaeOpenFd()) ++ return NULL; ++ ++ if (requested_pages > QAE_NUM_PAGES_PER_ALLOC * QAE_PAGE_SIZE / UNIT_SIZE || ++ phys_alignment_byte >= QAE_NUM_PAGES_PER_ALLOC * QAE_PAGE_SIZE) ++ { ++ mem_type = LARGE; ++ /* Huge page and Large memory are mutually exclusive ++ * Since Large slabs are NOT 2 MB aligned, but huge ++ * pages are always 2 MB aligned. ++ */ ++ if (hugepage_enabled()) ++ return NULL; ++ ++ size = MAX(size, phys_alignment_byte); ++ allocate_pages = div_round_up(size, UNIT_SIZE); ++ } ++ else ++ { ++ allocate_pages = QAE_NUM_PAGES_PER_ALLOC * QAE_PAGE_SIZE / UNIT_SIZE; ++ if (hugepage_enabled()) ++ mem_type = HUGE_PAGE; ++ ++ p_ctrl_blk = find_slab(fd, size, node, &pVirtAddress, phys_align_unit); ++ ++ if (p_ctrl_blk) ++ { ++ p_ctrl_blk->allocations += 1; ++ return pVirtAddress; ++ } ++ } ++ ++ /* Try to allocate memory as much as possible */ ++ p_ctrl_blk = alloc_slab(fd, allocate_pages * UNIT_SIZE, node, mem_type); ++ if (NULL == p_ctrl_blk) ++ return NULL; ++ ++ store_mmap_range(&g_page_table, ++ p_ctrl_blk->virt_addr, ++ p_ctrl_blk->phy_addr, ++ p_ctrl_blk->size, ++ hugepage_enabled()); ++ ++ if (LARGE == mem_type) ++ { ++ p_ctrl_blk->allocations = 1; ++ ++ ADD_ELEMENT_TO_HEAD_LIST( ++ p_ctrl_blk, pUserLargeMemListHead, pUserLargeMemListTail, _user); ++ ++ pVirtAddress = p_ctrl_blk->virt_addr; ++ } ++ else ++ { ++ p_ctrl_blk->allocations = 1; ++ ++ if ((uintptr_t)p_ctrl_blk->virt_addr % QAE_PAGE_SIZE) ++ { ++ CMD_ERROR("%s:%d Bad virtual address alignment %lux %x %lux\n", ++ __func__, ++ __LINE__, ++ (uintptr_t)p_ctrl_blk->virt_addr, ++ QAE_NUM_PAGES_PER_ALLOC, ++ QAE_PAGE_SIZE); ++ free_slab(fd, p_ctrl_blk); ++ ++ return NULL; ++ } ++ pVirtAddress = init_slab_and_alloc( ++ (block_ctrl_t *)p_ctrl_blk, size, phys_align_unit); ++ if (NULL == pVirtAddress) ++ { ++ CMD_ERROR("%s:%d Memory allocation failed Virtual address: %p " ++ " Size: %x \n", ++ __func__, ++ __LINE__, ++ p_ctrl_blk, ++ size); ++ free_slab(fd, p_ctrl_blk); ++ ++ return NULL; ++ } ++ } ++ return pVirtAddress; ++} ++ ++void *qaeMemAllocNUMA(size_t size, int node, size_t phys_alignment_byte) ++{ ++ void *pVirtAddress = NULL; ++ int ret = 0; ++ /* Maximum supported alignment is 4M. */ ++ const size_t MAX_PHYS_ALIGN = 0x400000; ++ ++ if (!size) ++ { ++ CMD_ERROR("%s:%d Size cannot be zero \n", __func__, __LINE__); ++ return NULL; ++ } ++ ++ if (!phys_alignment_byte || phys_alignment_byte > MAX_PHYS_ALIGN || ++ (phys_alignment_byte & (phys_alignment_byte - 1))) ++ { ++ CMD_ERROR("%s:%d Invalid alignment parameter %d. It must be non zero, " ++ "not more than %d and multiple of 2 \n", ++ __func__, ++ __LINE__, ++ phys_alignment_byte, ++ MAX_PHYS_ALIGN); ++ return NULL; ++ } ++ ++ ret = mem_mutex_lock(&mutex); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR("%s:%d Error on thread mutex lock %s\n", ++ __func__, ++ __LINE__, ++ strerror(ret)); ++ return NULL; ++ } ++ ++ pVirtAddress = alloc_addr(size, node, phys_alignment_byte); ++ ++ ret = mem_mutex_unlock(&mutex); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR("%s:%d Error on thread mutex unlock %s\n", ++ __func__, ++ __LINE__, ++ strerror(ret)); ++ return NULL; ++ } ++ return pVirtAddress; ++} ++ ++static inline void free_addr(void **p_va) ++{ ++ dev_mem_info_t *p_ctrl_blk = NULL; ++ ++ if (0 != qaeOpenFd()) ++ return; ++ ++ if ((p_ctrl_blk = find_slab_in_hash(*p_va)) == NULL) ++ { ++ CMD_ERROR("%s:%d Unable to free as lookup failed on address (%p) " ++ "provided \n", ++ __func__, ++ __LINE__, ++ *p_va); ++ return; ++ } ++ if (SMALL == p_ctrl_blk->type || HUGE_PAGE == p_ctrl_blk->type) ++ { ++ mem_free((block_ctrl_t *)p_ctrl_blk, *p_va); ++ ++ p_ctrl_blk->allocations -= 1; ++ ++ if (p_ctrl_blk->allocations) ++ { ++ *p_va = NULL; ++ return; ++ } ++ ++ REMOVE_ELEMENT_FROM_LIST( ++ p_ctrl_blk, pUserMemListHead, pUserMemListTail, _user); ++ if (0 != push_slab(p_ctrl_blk)) ++ free_slab(fd, p_ctrl_blk); ++ } ++ else ++ { ++ REMOVE_ELEMENT_FROM_LIST( ++ p_ctrl_blk, pUserLargeMemListHead, pUserLargeMemListTail, _user); ++ free_slab(fd, p_ctrl_blk); ++ } ++ *p_va = NULL; ++} ++ ++void qaeMemFreeNUMA(void **ptr) ++{ ++ int ret = 0; ++ ++ if (NULL == ptr) ++ { ++ CMD_ERROR( ++ "%s:%d Input parameter cannot be NULL \n", __func__, __LINE__); ++ return; ++ } ++ if (NULL == *ptr) ++ { ++ CMD_ERROR( ++ "%s:%d Address to be freed cannot be NULL \n", __func__, __LINE__); ++ return; ++ } ++ ret = mem_mutex_lock(&mutex); ++ if (ret) ++ { ++ CMD_ERROR("%s:%d Error on thread mutex lock %s\n", ++ __func__, ++ __LINE__, ++ strerror(ret)); ++ *ptr = NULL; ++ return; ++ } ++ ++ free_addr(ptr); ++ ++ ret = mem_mutex_unlock(&mutex); ++ if (ret) ++ { ++ CMD_ERROR("%s:%d Error on thread mutex unlock %s\n", ++ __func__, ++ __LINE__, ++ strerror(ret)); ++ } ++ return; ++} ++ ++/*translate a virtual address to a physical address */ ++uint64_t qaeVirtToPhysNUMA(void *pVirtAddress) ++{ ++ return load_addr_fptr(&g_page_table, pVirtAddress); ++} ++ ++static int32_t memoryRemap(dev_mem_info_t *head) ++{ ++ // NOT SUPPORTED ++ if (NULL != head) ++ { ++ CMD_ERROR("%s:%d not supported \n", __func__, __LINE__); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++void qaeAtFork() ++{ ++ int ret = 0; ++ int32_t status0 = 0; ++ int32_t status1 = 0; ++ int32_t status2 = 0; ++ ++ ret = mem_mutex_lock(&mutex); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR( ++ "%s:%d Error(%d) on thread mutex lock \n", __func__, __LINE__, ret); ++ return; ++ } ++ ++ status0 = memoryRemap(pUserCacheHead); ++ status1 = memoryRemap(pUserMemListHead); ++ status2 = memoryRemap(pUserLargeMemListHead); ++ ++ ret = mem_mutex_unlock(&mutex); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR("%s:%d Error on thread mutex unlock %s\n", ++ __func__, ++ __LINE__, ++ strerror(ret)); ++ goto fork_exit; ++ } ++ ++fork_exit: ++ if (unlikely(status0)) ++ { ++ CMD_ERROR( ++ "%s:%d Failed to remap memory allocations \n", __func__, __LINE__); ++ } ++ if (unlikely(status1)) ++ { ++ CMD_ERROR( ++ "%s:%d Failed to remap memory allocations \n", __func__, __LINE__); ++ } ++ if (unlikely(status2)) ++ { ++ CMD_ERROR("%s:%d Failed to remap large memory allocations \n", ++ __func__, ++ __LINE__); ++ } ++ return; ++} +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/user_space/qae_page_table.h +@@ -0,0 +1,431 @@ ++/******************************************************************************* ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ * @file qae_page_table.h ++ * ++ * This file provides user-space page tables (similar to Intel x86/x64 ++ * page tables) for fast virtual to physical address translation. Essentially, ++ * this is an implementation of the trie data structure optimized for the x86 HW ++ * constraints. ++ * Memory required: ++ * - 8 Mb to cover 4 Gb address space. ++ * I.e. if only 1 Gb is used it will require additional 2 Mb. ++ * ++ ******************************************************************************/ ++ ++#ifndef QAE_PAGE_TABLE_H_1 ++#define QAE_PAGE_TABLE_H_1 ++ ++#define __STDC_WANT_LIB_EXT1__ 1 ++#include ++#include ++#ifdef __linux__ ++#include ++#endif ++ ++#ifndef __FreeBSD__ /* FreeBSD, already defined in machine param.h */ ++#define PAGE_SIZE (0x1000) ++#define PAGE_SHIFT (12) ++#endif ++ ++#define QAE_PAGE_MASK (~(PAGE_SIZE - 1)) ++#define LEVEL_SIZE (PAGE_SIZE / sizeof(uint64_t)) ++ ++#define HUGEPAGE_SIZE (0x200000) ++#define HUGEPAGE_SHIFT (21) ++#define HUGEPAGE_MASK (~(HUGEPAGE_SIZE - 1)) ++ ++typedef struct ++{ ++ uint64_t offset : 12; ++ uint64_t idxl0 : 9; ++ uint64_t idxl1 : 9; ++ uint64_t idxl2 : 9; ++ uint64_t idxl3 : 9; ++ uint64_t idxl4 : 9; ++} page_entry_t; ++ ++typedef struct ++{ ++ uint64_t offset : 21; ++ uint64_t idxl1 : 9; ++ uint64_t idxl2 : 9; ++ uint64_t idxl3 : 9; ++ uint64_t idxl4 : 9; ++} hugepage_entry_t; ++ ++typedef union { ++ uint64_t addr; ++ page_entry_t pg_entry; ++ hugepage_entry_t hpg_entry; ++} page_index_t; ++ ++typedef struct page_table_t ++{ ++ union { ++ uint64_t pa; ++ struct page_table_t *pt; ++ } next[LEVEL_SIZE]; ++} page_table_t; ++ ++typedef void (*free_page_table_fptr_t)(page_table_t *const table); ++typedef void (*store_addr_fptr_t)(page_table_t *, uintptr_t, uint64_t); ++typedef uint64_t (*load_addr_fptr_t)(page_table_t *, void *); ++typedef uint64_t (*load_key_fptr_t)(page_table_t *, void *); ++ ++#ifndef __FreeBSD__ ++void set_free_page_table_fptr(free_page_table_fptr_t fp); ++void set_loadaddr_fptr(load_addr_fptr_t fp); ++void set_loadkey_fptr(load_key_fptr_t fp); ++#endif /* __FreeBSD__ */ ++ ++static inline void *qae_memzero(void *const ptr, const size_t count) ++{ ++ uint32_t lim = 0; ++ volatile unsigned char *volatile dstPtr = ptr; ++ ++ while (lim < count) ++ { ++ dstPtr[lim++] = '\0'; ++ } ++ return (void *)dstPtr; ++} ++ ++/* ++ * Fills a memory zone with 0, ++ * returns pointer to the memory zone. ++ */ ++static inline void *qae_memzero_explicit(void *const ptr, const size_t count) ++{ ++ if (!ptr) ++ { ++ return NULL; ++ } ++#if (defined(__linux__)) ++#ifdef __STDC_LIB_EXT1__ ++ errno_t result = ++ memset_s(ptr, sizeof(ptr), 0, count); /* Supported on C11 standard */ ++ if (result != 0) ++ { ++ return NULL; ++ } ++ return ptr; ++#endif /* __STDC_LIB_EXT1__ */ ++#elif (defined(__FreeBSD__)) ++ explicit_bzero(ptr, count); ++ return ptr; ++#endif /* __linux__ */ ++ return qae_memzero(ptr, count); /* Platform-independent secure memset */ ++} ++ ++static inline void *next_level(page_table_t *volatile *ptr) ++{ ++ page_table_t *old_ptr = *ptr; ++ page_table_t *new_ptr; ++ ++ if (NULL != old_ptr) ++ return old_ptr; ++ ++ new_ptr = mmap(NULL, ++ sizeof(page_table_t), ++ PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, ++ -1, ++ 0); ++ if ((void *)-1 == new_ptr) ++ return NULL; ++ ++ if (!__sync_bool_compare_and_swap(ptr, NULL, new_ptr)) ++ munmap(new_ptr, sizeof(page_table_t)); ++ ++ return *ptr; ++} ++ ++static inline void free_page_level(page_table_t *const level, const size_t iter) ++{ ++ size_t i = 0; ++ ++ if (0 == iter) ++ return; ++ ++ for (i = 0; i < LEVEL_SIZE; ++i) ++ { ++ page_table_t *pt = level->next[i].pt; ++ if (NULL != pt) ++ { ++ free_page_level(pt, iter - 1); ++ munmap(pt, sizeof(page_table_t)); ++ } ++ } ++} ++ ++static inline void free_page_table(page_table_t *const table) ++{ ++ /* There are 1+4 levels in 64-bit page table for 4KB pages. */ ++ free_page_level(table, 4); ++ /* Reset global root table. */ ++ memset(table, 0, sizeof(page_table_t)); ++} ++ ++#ifndef __FreeBSD__ ++static inline void free_page_table_hpg(page_table_t *const table) ++{ ++ /* There are 1+3 levels in 64-bit page table for 2MB hugepages. */ ++ free_page_level(table, 3); ++ /* Reset global root table. */ ++ memset(table, 0, sizeof(page_table_t)); ++} ++#endif /*__FreeBSD__ */ ++ ++static inline void store_addr(page_table_t *level, ++ uintptr_t virt, ++ uint64_t phys) ++{ ++ page_index_t id; ++ ++ id.addr = virt; ++ ++ level = next_level(&level->next[id.pg_entry.idxl4].pt); ++ if (NULL == level) ++ return; ++ ++ level = next_level(&level->next[id.pg_entry.idxl3].pt); ++ if (NULL == level) ++ return; ++ ++ level = next_level(&level->next[id.pg_entry.idxl2].pt); ++ if (NULL == level) ++ return; ++ ++ level = next_level(&level->next[id.pg_entry.idxl1].pt); ++ if (NULL == level) ++ return; ++ ++ level->next[id.pg_entry.idxl0].pa = phys; ++} ++ ++static inline void store_addr_hpg(page_table_t *level, ++ uintptr_t virt, ++ uint64_t phys) ++{ ++ page_index_t id; ++ ++ id.addr = virt; ++ ++ level = next_level(&level->next[id.hpg_entry.idxl4].pt); ++ if (NULL == level) ++ return; ++ ++ level = next_level(&level->next[id.hpg_entry.idxl3].pt); ++ if (NULL == level) ++ return; ++ ++ level = next_level(&level->next[id.hpg_entry.idxl2].pt); ++ if (NULL == level) ++ return; ++ ++ level->next[id.hpg_entry.idxl1].pa = phys; ++} ++ ++static inline uint64_t get_key(const uint64_t phys) ++{ ++ /* For 4KB page: use bits 20-31 of a physical address as a hash key. ++ * It provides a good distribution for 1Mb/2Mb slabs and a moderate ++ * distribution for 128Kb/256Kb/512Kbslabs. ++ */ ++ return (phys >> 20) & ~QAE_PAGE_MASK; ++} ++ ++static inline void store_mmap_range(page_table_t *p_level, ++ void *p_virt, ++ uint64_t p_phys, ++ size_t p_size, ++ int hp_en) ++{ ++ size_t offset; ++ size_t page_size = PAGE_SIZE; ++ uint64_t page_mask = QAE_PAGE_MASK; ++ store_addr_fptr_t store_addr_ptr = store_addr; ++ const uintptr_t virt = (uintptr_t)p_virt; ++ ++ if (hp_en) ++ { ++ page_size = HUGEPAGE_SIZE; ++ page_mask = HUGEPAGE_MASK; ++ store_addr_ptr = store_addr_hpg; ++ } ++ /* Store the key into the physical address itself, ++ * for 4KB pages: 12 lower bits are always 0 (physical page addresses ++ * are 4KB-aligned). ++ * for 2MB pages: 21 lower bits are always 0 (physical page addresses ++ * are 2MB-aligned) ++ */ ++ p_phys = (p_phys & page_mask) | get_key(p_phys); ++ for (offset = 0; offset < p_size; offset += page_size) ++ { ++ store_addr_ptr(p_level, virt + offset, p_phys + offset); ++ } ++} ++ ++static inline uint64_t load_addr(page_table_t *level, void *virt) ++{ ++ page_index_t id; ++ uint64_t phy_addr; ++ ++ id.addr = (uintptr_t)virt; ++ ++ level = level->next[id.pg_entry.idxl4].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.pg_entry.idxl3].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.pg_entry.idxl2].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.pg_entry.idxl1].pt; ++ if (NULL == level) ++ return 0; ++ ++ phy_addr = level->next[id.pg_entry.idxl0].pa; ++ return (phy_addr & QAE_PAGE_MASK) | id.pg_entry.offset; ++} ++ ++static inline uint64_t load_addr_hpg(page_table_t *level, void *virt) ++{ ++ page_index_t id; ++ uint64_t phy_addr; ++ ++ id.addr = (uintptr_t)virt; ++ ++ level = level->next[id.hpg_entry.idxl4].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.hpg_entry.idxl3].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.hpg_entry.idxl2].pt; ++ if (NULL == level) ++ return 0; ++ ++ phy_addr = level->next[id.hpg_entry.idxl1].pa; ++ return (phy_addr & HUGEPAGE_MASK) | id.hpg_entry.offset; ++} ++ ++static inline uint64_t load_key(page_table_t *level, void *virt) ++{ ++ page_index_t id; ++ uint64_t phy_addr; ++ ++ id.addr = (uintptr_t)virt; ++ ++ level = level->next[id.pg_entry.idxl4].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.pg_entry.idxl3].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.pg_entry.idxl2].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.pg_entry.idxl1].pt; ++ if (NULL == level) ++ return 0; ++ ++ phy_addr = level->next[id.pg_entry.idxl0].pa; ++ return phy_addr & ~QAE_PAGE_MASK; ++} ++ ++#ifndef __FreeBSD__ ++static inline uint64_t load_key_hpg(page_table_t *level, void *virt) ++{ ++ page_index_t id; ++ uint64_t phy_addr; ++ ++ id.addr = (uintptr_t)virt; ++ ++ level = level->next[id.hpg_entry.idxl4].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.hpg_entry.idxl3].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.hpg_entry.idxl2].pt; ++ if (NULL == level) ++ return 0; ++ ++ phy_addr = level->next[id.hpg_entry.idxl1].pa; ++ /* the hash key is of 4KB long for both normal page and huge page */ ++ return phy_addr & ~QAE_PAGE_MASK; ++} ++#endif /* __FreeBSD__ */ ++ ++#endif +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/qae_mem.h +@@ -0,0 +1,244 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++/** ++ *************************************************************************** ++ * @file qae_mem.h ++ * ++ * This file provides linux/FreeBSD memory allocation for quick assist API ++ * ++ ****************************************************************************/ ++#ifndef QAE_MEM_H_ ++#define QAE_MEM_H_ ++ ++#ifdef __KERNEL__ ++#ifdef __FreeBSD__ ++#include ++#else ++#include ++#endif ++#else ++#include ++#endif ++ ++/** ++ ***************************************************************************** ++ * @ingroup CommonMemoryDriver ++ * qaeMemAlloc ++ * ++ * @brief ++ * When used in user space, allocates memsize bytes of virtual memory. ++ * When used in kernel space, allocates memsize bytes of contigous and ++ * pinned memory. ++ * ++ * @param[in] memsize - the amount of memory in bytes to be allocated ++ * ++ * @retval pointer to the allocated memory or NULL if the allocation failed ++ * ++ * @pre ++ * none ++ * @post ++ * memory is allocated and the pointer to the allocated memory location ++ * is returned ++ * ++ ****************************************************************************/ ++void *qaeMemAlloc(size_t memsize); ++ ++/** ++ ***************************************************************************** ++ * @ingroup CommonMemoryDriver ++ * qaeMemFree ++ * ++ * @brief ++ * Frees memory allocated by the qaeMemAlloc function. ++ * Applicable for both user and kernel spaces. ++ * ++ * @param[in] ptr - Address of the pointer to the memory to be freed ++ * ++ * @retval none ++ * ++ * @pre ++ * *ptr points to memory previously allocated by qaeMemAlloc ++ * @post ++ * memory is freed and pointer value is set to NULL ++ * ++ ****************************************************************************/ ++void qaeMemFree(void **ptr); ++ ++/** ++ ***************************************************************************** ++ * @ingroup CommonMemoryDriver ++ * qaeMemAllocNUMA ++ * ++ * @brief ++ * Allocates and returns virtual memory mapped to pinned, contiguous ++ * physical memory aligned to phys_alignment_byte. This API enables ++ * user to choose a CPU node nearest to QAT device. This API is applicable ++ * for both user and kernel spaces. Based on the address space used, ++ * memory mapped from corresponding virtual address space will be returned. ++ * ++ * @param[in] size - A non-zero value representing the amount of memory in ++ * bytes to be allocated.It cannot exceed 4MB ++ * @param[in] node - NUMA node ++ * @param[in] phys_alignment_byte - A non-zero value representing memory ++ * boundary alignment in bytes. It must ++ * be in powers of 2 not exceeding 4KB. ++ * ++ * @retval pointer to the allocated memory or NULL if the allocation failed ++ * ++ * @pre ++ * none ++ * @post ++ * memory is allocated and pointer to the allocated memory is returned ++ * ++ ****************************************************************************/ ++void *qaeMemAllocNUMA(size_t size, int node, size_t phys_alignment_byte); ++ ++/** ++ ***************************************************************************** ++ * @ingroup CommonMemoryDriver ++ * qaeMemFreeNUMA ++ * ++ * @brief ++ * Frees memory allocated by the qaeMemAllocNUMA function. ++ * Applicable for both user and kernel spaces. ++ * ++ * @param[in] ptr - Address of pointer to the memory to be freed ++ * ++ * @retval none ++ * ++ * @pre ++ * *ptr points to memory previously allocated by qaeMemAllocNUMA ++ * @post ++ * memory is freed and the pointer value is set to NULL ++ * ++ ****************************************************************************/ ++void qaeMemFreeNUMA(void **ptr); ++ ++/** ++ ***************************************************************************** ++ * @ingroup CommonMemoryDriver ++ * qaeVirtToPhysNUMA ++ * ++ * @brief ++ * Converts a virtual address provided by qaeMemAllocNUMA to a ++ * physical one. Applicable for both user and kernel spaces. ++ * ++ * @param[in] pVirtAddr - pointer to the virtual address ++ * ++ * @retval pointer to the physical address or 0(NULL) on error ++ * ++ * @pre ++ * pVirtAddr points to memory previously allocated by qaeMemAllocNUMA ++ * @post ++ * Appropriate physical address is provided ++ * ++ ****************************************************************************/ ++uint64_t qaeVirtToPhysNUMA(void *pVirtAddr); ++ ++#ifdef __FreeBSD__ ++/** ++ ***************************************************************************** ++ * @ingroup CommonMemoryDriver ++ * qaeMemInitAndReturnFd ++ * ++ * @description ++ * Returns the FD obtained by qaeMemInit ++ * ++ * @param[in] ++ * ptr - Address of fd which is updated by qaeMemInit ++ * ++ * @retval ++ * status from qaeMemInit. 0 if the open of the device was successful and ++ * non-zero otherwise ++ * ++ * @pre ++ * File "/dev/qae_mem" is opened successfully ++ * @post ++ * none ++ * ++ ****************************************************************************/ ++int qaeMemInitAndReturnFd(int *mem_fd); ++#endif ++ ++#ifndef __KERNEL__ ++/*! Define a constant for user space to select any available NUMA node */ ++#define NUMA_ANY_NODE (-1) ++ ++/** ++ *************************************************************************** ++ * @ingroup CommonMemoryDriver ++ * qaeAtFork ++ * ++ * @brief ++ * Must be called when child process is forked to adjust the kernel ++ * memory map page. ++ * ++ * @param[in] - none ++ * ++ * @retval none ++ * ++ ****************************************************************************/ ++void qaeAtFork(void); ++#endif ++ ++#endif /* #ifndef QAE_MEM_H_ */ +--- a/quickassist/include/cpa.h ++++ b/quickassist/include/cpa.h +@@ -694,13 +694,21 @@ typedef enum _CpaInstanceEvent + * implementation may send this event if the hardware device is about to + * be reset. + */ +- CPA_INSTANCE_EVENT_RESTARTED ++ CPA_INSTANCE_EVENT_RESTARTED, + /**< Event type that triggers the registered instance notification callback + * function when and instance has restarted. The reason why an instance has + * restarted is implementation specific. For example a hardware + * implementation may send this event after the hardware device has + * been reset. + */ ++ ++ CPA_INSTANCE_EVENT_FATAL_ERROR ++ /**< Event type that triggers the registered instance notification callback ++ * function when an error has been detected that requires the device ++ * to be reset. ++ * This event will be sent by all instances using the device, both on the ++ * host and guests. ++ */ + } CpaInstanceEvent; + + #ifdef __cplusplus diff --git a/package/qat/firmware/quickassist-c3xxx/Config.in b/package/qat/firmware/quickassist-c3xxx/Config.in new file mode 100644 index 000000000..6839abf00 --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/Config.in @@ -0,0 +1,104 @@ +menu "Configuration" + depends on PACKAGE_quickassist-c3xxx + + config QAT_C3XXX_KERNEL_OPTIONS + bool + default y + prompt "Required kernel options for Quickassist" + select KERNEL_ASN1 + select KERNEL_CRYPTO_AKCIPHER + select KERNEL_CRYPTO_AKCIPHER2 + select KERNEL_CRYPTO_DH + select KERNEL_CRYPTO_HW + select KERNEL_CRYPTO_KPP + select KERNEL_CRYPTO_KPP2 + select KERNEL_CRYPTO_RSA + select KERNEL_UIO + select KERNEL_PCI_IOV + select KERNEL_HUGETLBFS + select KERNEL_HUGETLB_PAGE + help + These kernel options are required for successful compilation and runtime functionality. + + config QAT_DEBUG + bool + default n + prompt "Build with debugging support enabled" + + config QAT_DISABLE_STATS + bool + default n + prompt "Disable statistics collection" + help + Disable for performance optimization + + config QAT_LOG_SYSLOG + bool + default y + prompt "Debug to syslog instead of stdout" + + config QAT_PARAM_CHECK + bool + default y + prompt "Enable parameter checking in the top-level APIs" + help + Disable for performance optimization + + config QAT_NONBLOCKING_PARTIALS + bool + default y + prompt "Partial operation results are non-blocking" + help + Disable for performance optimization + + config QAT_DC_ONLY + bool + default n + prompt "Build acceleration only for compression" + help + Optimize for size if using only compression + + config QAT_DC_SYM_ONLY + bool + default n + prompt "Build acceleration only for compression and symmetric ciphers" + help + Optimize for size if using only compression and symmetric ciphers + + config QAT_DC_COUNTER_ERROR + bool + default n + prompt "Update counters when encountering an error" + help + Enables updates of consumed/produced results in case + of error during compression or decompression operations + + config QAT_DISABLE_INLINE + bool + default n + prompt "Disable functioning inlining for functions that cannot be inlined by the compiler" + help + Use where kernel does not support CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING to allow building + + config QAT_HB_FAIL + bool + default n + prompt "Enable heartbeat failure simulation" + + config QAT_COEXIST + bool + default n + prompt "Enable legacy and upstream driver coexistence" + + config QAT_LKCF + bool + default y + prompt "Enable QAT registration with Linux Kernel Crypto Framework" + + config QAT_DISABLE_STRICT + bool + default n + prompt "Disable strict mode for data compression" + +endmenu + diff --git a/package/qat/firmware/quickassist-c3xxx/Config.kernel b/package/qat/firmware/quickassist-c3xxx/Config.kernel new file mode 100644 index 000000000..0874bbf9f --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/Config.kernel @@ -0,0 +1,97 @@ +config KERNEL_ASN1 + bool + default n + +config KERNEL_CRYPTO_AKCIPHER + bool + default n + +config KERNEL_CRYPTO_AKCIPHER2 + bool + default n + +config KERNEL_CRYPTO_DH + bool + default n + +config KERNEL_CRYPTO_KPP + bool + default n + +config KERNEL_CRYPTO_KPP2 + bool + default n + +config KERNEL_CRYPTO_RSA + bool + default n + +config KERNEL_HUGETLBFS + bool + default n + +config KERNEL_HUGETLB_PAGE + bool + default n + +config KERNEL_CRYPTO_HW + bool + default n + +config KERNEL_UIO + bool + default n + +config KERNEL_PCI_IOV + bool + default n + +# CONFIG_UIO is not set in generic and x86 kernels +# Avoid prompting the user for input of dependent symbols + +config KERNEL_UIO_CIF + bool + default n + +config KERNEL_UIO_PDRV_GENIRQ + bool + default n + +config KERNEL_UIO_DMEM_GENIRQ + bool + default n + +config KERNEL_UIO_AEC + bool + default n + +config KERNEL_UIO_SERCOS3 + bool + default n + +config KERNEL_UIO_PCI_GENERIC + bool + default n + +config KERNEL_UIO_NETX + bool + default n + +config KERNEL_UIO_PRUSS + bool + default n + +config KERNEL_UIO_MF624 + bool + default n + +config KERNEL_UIO_HV_GENERIC + bool + default n + +# CONFIG_STAGING is set in generic +# CONFIG_KPC2000 depends on PCI and UIO + +config KERNEL_KPC2000 + bool + default n diff --git a/package/qat/firmware/quickassist-c3xxx/Makefile b/package/qat/firmware/quickassist-c3xxx/Makefile new file mode 100644 index 000000000..87e83c4cd --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/Makefile @@ -0,0 +1,236 @@ +# +# Copyright (C) Ian Cooper +# +# This is free software, licensed under the GNU General Public License v3. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=quickassist-c3xxx + +PKG_VERSION:=1.7 +PKG_MINOR_VERSION:=L.4.17.0-00002 +PKG_RELEASE:=1 + +PKG_SOURCE:=QAT.$(PKG_MINOR_VERSION).tar.gz +PKG_SOURCE_URL:=https://downloadmirror.intel.com/727448/ +PKG_HASH:=skip + +PKG_LICENSE:=GPL v3 + +PKG_BUILD_DEPENDS:=eudev openssl +QAT_DEFAULT_DEPENDS:= @TARGET_x86_64 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +PKG_BUILD_PARALLEL:=0 + +QAT_BUILD = $(PKG_BUILD_DIR)/build +QAT_BLDSYS = $(PKG_BUILD_DIR)/quickassist/build_system +QAT_OOT = $(PKG_BUILD_DIR)/quickassist/qat +QAT_ADF = $(PKG_BUILD_DIR)/quickassist/utilities/adf_ctl +QAT_ENV = $(PKG_BUILD_DIR)/quickassist/build_system/build_files/env_files + +define Package/quickassist-c3xxx + SECTION:=firmware + CATEGORY:=Firmware + TITLE:=Intel Quick Assist Technology for c3xxx SoC + DEPENDS:= \ + $(QAT_DEFAULT_DEPENDS) \ + $(PKG_DEFAULT_DEPENDS) \ + +libopenssl \ + +libstdcpp \ + +eudev \ + +kmod-itco-wdt \ + +kmod-crypto-manager \ + +kmod-crypto-sha1 \ + +kmod-crypto-sha256 \ + +kmod-crypto-sha512 \ + +kmod-crypto-cbc \ + +kmod-crypto-qat-c3xxx \ + +kmod-crypto-qat-usdm \ + +kmod-crypto-qat-common \ + +kmod-crypto-qat-api + USERID:=qat=555:qat=555 +endef + +define Package/quickassist-c3xxx/description + Intel Quick Assist v1.7 drivers and utilities for c3xxx series SoCs +endef + +define Package/quickassist-c3xxx/config + source "$(SOURCE)/Config.kernel" + source "$(SOURCE)/Config.in" + config quickassist-c3xxx-enabled + bool + default y if PACKAGE_quickassist-c3xxx + default n +endef + +define KernelPackage/crypto-qat-c3xxx + SUBMENU:=Cryptographic API modules + TITLE:=Intel Quick Assist Technology Driver + DEPENDS:= \ + $(QAT_DEFAULT_DEPENDS) \ + kmod-crypto-qat-common + FILES:=$(QAT_OOT)/drivers/crypto/qat/qat_c3xxx/qat_c3xxx.ko +endef + +define KernelPackage/crypto-qat-c3xxx/description + Kernel driver for Intel Quick Assist Technology c3xxx +endef + +define KernelPackage/crypto-qat-common + SUBMENU:=Cryptographic API modules + TITLE:=Intel Quick Assist Common Driver + DEPENDS:= \ + $(QAT_DEFAULT_DEPENDS) \ + +kmod-crypto-authenc \ + +kmod-crypto-kpp + FILES:=$(QAT_OOT)/drivers/crypto/qat/qat_common/intel_qat.ko +endef + +define KernelPackage/crypto-qat-common/description + Kernel driver shared layer for Intel Quick Assist Technology c3xxx +endef + +define KernelPackage/crypto-qat-common/config + depends on quickassist-c3xxx-enabled +endef + +define KernelPackage/crypto-qat-api + SUBMENU:=Cryptographic API modules + TITLE:=Intel Quick Assist Kernel API + DEPENDS:= \ + $(QAT_DEFAULT_DEPENDS) \ + kmod-crypto-qat-common + FILES:=$(QAT_BUILD)/qat_api.ko +endef + +define KernelPackage/crypto-qat-api/description + Kernel API for Intel Quick Assist Technology c3xxx +endef + +define KernelPackage/crypto-qat-usdm + SUBMENU:=Cryptographic API modules + TITLE:=Intel Quick Assist Pinned Memory Driver + DEPENDS:= \ + $(QAT_DEFAULT_DEPENDS) \ + kmod-crypto-qat-common + FILES:=$(QAT_BUILD)/usdm_drv.ko +endef + +define KernelPackage/crypto-qat-usdm/description + Contiguous pinned memory driver for Intel Quick Assist Technology +endef + +ICP_ARCH = x86_64 +MAKE_PATH = quickassist + +QAT_CONFIG += $(if $(CONFIG_QAT_DEBUG) ,ICP_DEBUG="1",) +QAT_CONFIG += $(if $(CONFIG_QAT_DISABLE_STATS) ,DISABLE_STATS="1",) +QAT_CONFIG += $(if $(CONFIG_QAT_LOG_SYSLOG) ,ICP_LOG_SYSLOG="1",) +QAT_CONFIG += $(if $(CONFIG_QAT_PARAM_CHECK) ,ICP_PARAM_CHECK="y",) +QAT_CONFIG += $(if $(CONFIG_QAT_NONBLOCKING_PARTIALS) ,ICP_NONBLOCKING_PARTIALS_PERFORM="1",) +QAT_CONFIG += $(if $(CONFIG_QAT_DC_ONLY) ,ICP_DC_ONLY="1",) +QAT_CONFIG += $(if $(CONFIG_QAT_DC_ONLY) ,DO_CRYPTO="0",) +QAT_CONFIG += $(if $(CONFIG_QAT_DC_SYM_ONLY) ,ICP_DC_SYM_ONLY_AM="1",) +QAT_CONFIG += $(if $(CONFIG_QAT_DC_COUNTER_ERROR) ,ICP_DC_RETURN_COUNTERS_ON_ERROR="1",) +QAT_CONFIG += $(if $(CONFIG_QAT_DISABLE_INLINE) ,ICP_DISABLE_INLINE="1",) +QAT_CONFIG += $(if $(CONFIG_QAT_HB_FAIL) ,ICP_HB_FAIL_SYM="y",) +QAT_CONFIG += $(if $(CONFIG_QAT_COEXIST) ,QAT_COEXISTENCE="y",) +QAT_CONFIG += $(if $(CONFIG_QAT_LKCF) ,QAT_NO_LKCF="n",) +QAT_CONFIG += $(if $(CONFIG_QAT_DISABLE_STRICT) ,CNV_STRICT_MODE="1",) +QAT_CONFIG += $(if $(CONFIG_PKG_CC_STACKPROTECTOR_NONE) ,ICP_DEFENSES_ENABLED="n",ICP_DEFENSES_ENABLED="y") + +MAKE_VARS += ICP_ROOT="$(PKG_BUILD_DIR)" \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + CXX="$(TARGET_CXX)" \ + KERNEL_SOURCE_ROOT="$(LINUX_DIR)" \ + KERNEL_SOURCE_DIR="$(QAT_OOT)" \ + KDIR="$(LINUX_DIR)" \ + MACHINE="$(ICP_ARCH)" \ + USE_OPENSSL="1" \ + ICP_BUILD_OUTPUT="$(QAT_BUILD)" \ + ICP_ENV_DIR="$(QAT_ENV)" \ + ICP_BUILDSYSTEM_PATH="$(QAT_BLDSYS)" \ + ICP_TOOLS_TARGET="accelcomp" \ + $(QAT_CONFIG) \ + ICP_KAPI_M="1" \ + ICP_CORE="ia" \ + ICP_OS="linux_2.6" \ + ICP_ARCH_USER="$(ICP_ARCH)" \ + ICP_DEFENSES_ENABLED="n" \ + LIB_SHARED_FLAGS="-L $(STAGING_DIR)/lib -L $(STAGING_DIR)/usr/lib" \ + LD_LIBRARY_PATH="$(PKG_BUILD_DIR)/build" + +# ICP_DEFENSES_ENABLED="$(ICP_DEFENSES_ENABLED)" \ + +define Build/Prepare + (mkdir -p '$(PKG_BUILD_DIR)' && zcat '$(DL_DIR)/$(PKG_SOURCE)' | tar -C '$(PKG_BUILD_DIR)' -xf -) + $(Build/Patch) +endef + +define Build/Configure + # The shipped configure script is hopelessly broken for cross compilation environments +endef + +define Build/Compile + @echo "QAT Build Configuration: $(QAT_CONFIG)" + $(call Build/Compile/Default, -C $(QAT_OOT)) + $(call Build/Compile/Default, lac_kernel lac_user) + $(call Build/Compile/Default, -C $(QAT_ADF)) +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include + $(INSTALL_DIR) $(1)/usr/lib + $(INSTALL_DIR) $(1)/usr/icp/quickassist + $(INSTALL_DIR) $(1)/usr/icp/build + $(CP) $(PKG_BUILD_DIR)/build/lib*.{a,so*} $(1)/usr/lib/ + $(CP) $(PKG_BUILD_DIR)/quickassist/include/{*.h,dc,lac} $(1)/usr/include + $(CP) $(PKG_BUILD_DIR)/quickassist/lookaside/access_layer/include/*.h $(1)/usr/include + $(CP) $(PKG_BUILD_DIR)/quickassist $(1)/usr/icp + $(CP) $(PKG_BUILD_DIR)/build $(1)/usr/icp +endef + +define Package/quickassist-c3xxx/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/etc/hotplug.d + $(INSTALL_DIR) $(1)/etc/sysctl.d + $(INSTALL_DIR) $(1)/lib/firmware + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_DIR) $(1)/usr/share/quickassist/QAT1.7/config + $(CP) $(PKG_BUILD_DIR)/quickassist/utilities/adf_ctl/conf_files/c3xxx* $(1)/usr/share/quickassist/QAT1.7/config + $(CP) $(PKG_BUILD_DIR)/quickassist/utilities/adf_ctl/adf_ctl $(1)/usr/sbin/adf_ctl + $(CP) $(PKG_BUILD_DIR)/build/*.so* $(1)/lib/ + $(CP) $(PKG_BUILD_DIR)/quickassist/qat/fw/qat_c3xxx* $(1)/lib/firmware/ + $(CP) ./files/qat.init $(1)/etc/init.d/qat + $(CP) ./files/hotplug.d $(1)/etc + $(CP) ./files/sysctl.d $(1)/etc + $(CP) ./files/c3xxx_dev0.conf $(1)/etc/c3xxx_dev0.conf + $(CP) ./files/c3xxx_dev0.conf.multi $(1)/etc/c3xxx_dev0.conf.multi +endef + +define Package/quickassist-c3xxx/postinst +#!/bin/sh +[ -n "$${IPKG_INSTROOT}" ] && exit 0 +[ "$${PKG_UPGRADE}" = "1" ] && exit 0 +sysctl -p /etc/sysctl.d/12-hugepages.conf +/etc/init.d/qat enable +exit 0 +endef + +define Package/quickassist-c3xxx/prerm +#!/bin/sh +[ -n "$${IPKG_INSTROOT}" ] && exit 0 +/etc/init.d/qat stop +exit 0 +endef + +$(eval $(call BuildPackage,quickassist-c3xxx)) +$(eval $(call KernelPackage,crypto-qat-c3xxx)) +$(eval $(call KernelPackage,crypto-qat-common)) +$(eval $(call KernelPackage,crypto-qat-api)) +$(eval $(call KernelPackage,crypto-qat-usdm)) diff --git a/package/qat/firmware/quickassist-c3xxx/files/c3xxx_dev0.conf b/package/qat/firmware/quickassist-c3xxx/files/c3xxx_dev0.conf new file mode 100644 index 000000000..1e68e9a63 --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/c3xxx_dev0.conf @@ -0,0 +1,121 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2020 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2020 Intel Corporation. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +################################################################ +[GENERAL] +ServicesEnabled = cy + +# Set the service profile to determine available features +# ===================================================================== +# DEFAULT CRYPTO COMPRESSION CUSTOM1 +# Asymmetric Crypto * * * +# Symmetric Crypto * * * +# MGF KeyGen * * +# SSL/TLS KeyGen * * * +# HKDF * * +# Compression * * * +# Decompression (stateless) * * * +# Decompression (stateful) * * +# Service Chaining * +# Device Utilization * * +# Rate Limiting * * +# ===================================================================== +ServicesProfile = DEFAULT + +ConfigVersion = 2 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 64 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 0 +NumberDcInstances = 0 + +############################################## +# User Process Instance Section +############################################## +[SHIM] +NumberCyInstances = 1 +NumberDcInstances = 0 +NumProcesses = 32 +LimitDevAccess = 1 + +# Crypto - User instance #0 +Cy0Name = "UserCY0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 0 diff --git a/package/qat/firmware/quickassist-c3xxx/files/c3xxx_dev0.conf.multi b/package/qat/firmware/quickassist-c3xxx/files/c3xxx_dev0.conf.multi new file mode 100644 index 000000000..d69bbe241 --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/c3xxx_dev0.conf.multi @@ -0,0 +1,127 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2020 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2020 Intel Corporation. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +################################################################ +[GENERAL] +ServicesEnabled = cy + +# Set the service profile to determine available features +# ===================================================================== +# DEFAULT CRYPTO COMPRESSION CUSTOM1 +# Asymmetric Crypto * * * +# Symmetric Crypto * * * +# MGF KeyGen * * +# SSL/TLS KeyGen * * * +# HKDF * * +# Compression * * * +# Decompression (stateless) * * * +# Decompression (stateful) * * +# Service Chaining * +# Device Utilization * * +# Rate Limiting * * +# ===================================================================== +ServicesProfile = DEFAULT + +ConfigVersion = 2 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 64 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 0 +NumberDcInstances = 0 + +############################################## +# User Process Instance Section +############################################## +[SHIM] +NumberCyInstances = 2 +NumberDcInstances = 0 +NumProcesses = 4 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "UserCY0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 0 + +# Crypto - User instance #1 +Cy1Name = "UserCY1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 0 diff --git a/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/module/01-usdm b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/module/01-usdm new file mode 100755 index 000000000..c6b2375ad --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/module/01-usdm @@ -0,0 +1,32 @@ +#!/bin/sh + +HUGE_PAGE_DIR="/dev/hugepages" + +[ "$DEVICENAME" != "usdm_drv" ] && exit 0 + +[ "$ACTION" == "add" ] && { + + if [ -d ${HUGE_PAGE_DIR} ]; then + + mkdir ${HUGE_PAGE_DIR}/qat 2> /dev/null + + if [ $? -ne 0]; then + logger -t "quickassist(usdm_drv): error creating ${HUGE_PAGE_DIR}/qat" + else + chgrp qat ${HUGE_PAGE_DIR}/qat + chmod 0770 ${HUGE_PAGE_DIR}/qat + fi + + else + logger -t "quickassist(usdm_drv): ${HUGE_PAGE_DIR} not found" + exit 1 + fi + + +} + +[ "$ACTION" == "remove" ] && { + + rmdir ${HUGE_PAGE_DIR}/qat + +} diff --git a/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/qat_adf_ctl/01-qat_adf_ctl b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/qat_adf_ctl/01-qat_adf_ctl new file mode 100644 index 000000000..565b619c5 --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/qat_adf_ctl/01-qat_adf_ctl @@ -0,0 +1,8 @@ +#!/bin/sh + +if [ "$DEVICENAME" != "qat_adf_ctl" ] && [ "$ACTION" != "add" ]; then exit 0; fi + +chgrp qat /dev/qat_adf_ctl +chmod 0660 /dev/qat_adf_ctl + + diff --git a/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/qat_dev_processes/01-qat_dev_processes b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/qat_dev_processes/01-qat_dev_processes new file mode 100644 index 000000000..2b6d0fac2 --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/qat_dev_processes/01-qat_dev_processes @@ -0,0 +1,8 @@ +#!/bin/sh + +if [ "$DEVICENAME" != "qat_dev_processes" ] && [ "$ACTION" != "add" ]; then exit 0; fi + +chgrp qat /dev/qat_dev_processes +chmod 0660 /dev/qat_dev_processes + + diff --git a/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/uio/01-uio b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/uio/01-uio new file mode 100644 index 000000000..fb4ae8335 --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/uio/01-uio @@ -0,0 +1,7 @@ +#!/bin/sh + +if [ "$ACTION" != "add" ] && [ "$MAJOR" != "249" ]; then exit 0; fi + +chgrp qat /dev/${DEVICENAME} +chmod 0660 /dev/${DEVICENAME} + diff --git a/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/usdm_drv/01-usdm b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/usdm_drv/01-usdm new file mode 100644 index 000000000..79216d7f7 --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/usdm_drv/01-usdm @@ -0,0 +1,8 @@ +#!/bin/sh + +if [ "$DEVICENAME" != "usdm_drv" ] && [ "$ACTION" != "add" ]; then exit 0; fi + +chgrp qat /dev/usdm_drv +chmod 0660 /dev/usdm_drv + + diff --git a/package/qat/firmware/quickassist-c3xxx/files/qat.init b/package/qat/firmware/quickassist-c3xxx/files/qat.init new file mode 100755 index 000000000..3fffd4c21 --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/qat.init @@ -0,0 +1,175 @@ +#!/bin/sh /etc/rc.common + +################################################################# + +# qat Start/Stop the Intel QAT. +# + +START=29 +STOP=99 + +ADF_CTL=/usr/sbin/adf_ctl +QAT_GID=200 +INTEL_VENDORID="8086" +C3XX_DEVICE_PCI_ID="19e2" +NUM_C3XXX_DEVICES=$(lspci -n | egrep -c "$INTEL_VENDORID:$C3XX_DEVICE_PCI_ID") +HUGE_PAGE_DIR=/dev/hugepages +HUGE_PAGE_MOUNT=$(mount | grep hugetlbfs | awk '{print $3}') +MAX_HUGE_PAGES=200 +MAX_HUGE_PAGES_PER_PROCESS=10 + +EXTRA_COMMANDS="status" +EXTRA_HELP=" status Show the status of the qat device" + + +qat_started() { + + ${ADF_CTL} status > /dev/null 2>&1 + return $? + +} + + +status() { + + ${ADF_CTL} status + if [ "$?" -ne 0 ] + then + echo "No devices found. Please start the driver using:" + echo "$0 start" + fi + +} + +insert_digest_modules() { + + if [ $(lsmod | grep -c "sha512") == 0 ]; then + + if [ $(cat /proc/kallsyms |grep -c sha512_) == 0 ]; then + modprobe sha512_ssse3 + else + echo "$0 no sha512_ssse3 module to load" + return 1 + fi + + fi + + if [ $(lsmod | grep -c "sha256") == 0 ]; then + + if [ $(cat /proc/kallsyms |grep -c sha256_) == 0 ]; then + modprobe sha256_ssse3 + else + echo "$0 no sha256_ssse3 module to load" + return 1 + fi + + fi + + return 0 + +} + +mount_hugetlbfs() { + + if [ "${HUGE_PAGE_MOUNT}" != "${HUGE_PAGE_DIR}" ]; then + + [ ! -d ${HUGE_PAGE_DIR} ] && mkdir ${HUGE_PAGE_DIR} + + mount -t hugetlbfs hugetlbfs ${HUGE_PAGE_DIR} -o mode=1770 -o gid=${QAT_GID} + + if [ $? -ne 0 ]; then + echo "$0: error mounting hugetlbfs on ${HUGE_PAGE_DIR}" + return 1 + fi + + fi + + return 0 + +} + +insert_modules() { + + # common functions kernel module + + if [ $(lsmod | grep "intel_qat" | wc -l) == "0" ]; then + modprobe intel_qat + fi + + [ $? -ne 0 ] && return 1 + + # contiguous pinned memory driver + # requires huge pages support in the kernel + + if [ $(lsmod | grep "usdm_drv" | wc -l) == "0" ]; then + modprobe usdm_drv max_huge_pages=${MAX_HUGE_PAGES} max_huge_pages_per_process=${MAX_HUGE_PAGES_PER_PROCESS} + fi + + [ $? -ne 0 ] && return 1 + + # qat device driver + + if [ $(lsmod | grep "qat_c3xxx" | wc -l) == "0" ]; then + modprobe qat_c3xxx + fi + + [ $? -ne 0 ] && return 1 + + # qat kernel api + + if [ $(lsmod | grep "qat_api" | wc -l) == "0" ]; then + modprobe qat_api + fi + + return $? + +} + +start() { + + /sbin/depmod -a 2> /dev/null + + qat_started + + if [ $? -ne 0 ]; then + + insert_digest_modules && [ $? -eq 0 ] && mount_hugetlbfs + + if [ $? -eq 0 ]; then + + if [ ${NUM_C3XXX_DEVICES} != 0 ]; then + insert_modules + [ $? -eq 0 ] && ${ADF_CTL} restart + fi + + fi + + else echo "QAT already started $?"; fi + + ${ADF_CTL} status + +} + +stop() { + + qat_started + + if [ $? -eq 0 ]; then + + ${ADF_CTL} down + rmmod usdm_drv + rmmod qat_api + rmmod qat_c3xxx + rmmod intel_qat + umount ${HUGE_PAGE_DIR} + + fi + +} + +restart() { + + ${ADF_CTL} restart + +} + diff --git a/package/qat/firmware/quickassist-c3xxx/files/sysctl.d/12-hugepages.conf b/package/qat/firmware/quickassist-c3xxx/files/sysctl.d/12-hugepages.conf new file mode 100644 index 000000000..2fdeb45bf --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/sysctl.d/12-hugepages.conf @@ -0,0 +1,5 @@ +# setup huge page maximums +# default size is 2MB + +vm.nr_hugepages=256 +vm.hugetlb_shm_group=200 diff --git a/package/qat/firmware/quickassist-c3xxx/patches/0001-fix-build.patch b/package/qat/firmware/quickassist-c3xxx/patches/0001-fix-build.patch new file mode 100644 index 000000000..f2da22eee --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/patches/0001-fix-build.patch @@ -0,0 +1,32 @@ +From 5a59b3e55b45d9ca6b7f96f3d6a30406aa1b715f Mon Sep 17 00:00:00 2001 +From: W_Y_CPP <383152993@qq.com> +Date: Sun, 24 Apr 2022 02:53:15 -0400 +Subject: [PATCH] fix build + +--- + quickassist/utilities/osal/src/linux/user_space/OsalServices.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/quickassist/utilities/osal/src/linux/user_space/OsalServices.c b/quickassist/utilities/osal/src/linux/user_space/OsalServices.c +index e650330e7..aae8c3040 100644 +--- a/quickassist/utilities/osal/src/linux/user_space/OsalServices.c ++++ b/quickassist/utilities/osal/src/linux/user_space/OsalServices.c +@@ -360,6 +360,7 @@ OSAL_PUBLIC UINT64 osalTimestampGet(void) + OSAL_PUBLIC UINT64 osalTimestampGetNs(void) + { + OsalTimeval ptime; ++#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) + #if __GLIBC_PREREQ(2, 17) + struct timespec tspec; + +@@ -372,6 +373,7 @@ OSAL_PUBLIC UINT64 osalTimestampGetNs(void) + OSAL_LOG_DEV_STDOUT, + "osalTimestampGetNs(): clock_gettime(CLOCK_REALTIME) system call " + "failed. Invoking osalTimeGet() as fallback\n"); ++#endif + #endif + ptime.secs = 0; + ptime.nsecs = 0; +-- +2.17.1 + diff --git a/package/qat/firmware/quickassist-c3xxx/patches/0001-remove-host-dependent-stack-protection-check.patch b/package/qat/firmware/quickassist-c3xxx/patches/0001-remove-host-dependent-stack-protection-check.patch new file mode 100644 index 000000000..4595a69cd --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/patches/0001-remove-host-dependent-stack-protection-check.patch @@ -0,0 +1,15 @@ +--- a/quickassist/build_system/build_files/env_files/environment.mk ++++ b/quickassist/build_system/build_files/env_files/environment.mk +@@ -59,11 +59,7 @@ DIRECT_PATH=$(ICP_ROOT)/quickassist/look + KERNEL_PATH=$(ICP_ROOT)/quickassist/lookaside/access_layer/src/qat_kernel/ + CMN_MEM_PATH=$(ICP_ROOT)/quickassist/utilities/libusdm_drv + ICP_DEFENSES_ENABLED ?= y +-ifeq ($(shell cat /proc/kallsyms | grep -w "__stack_chk_fail" | wc -l), 1) +-KERNEL_DEFENSES_STACK_PROTECTION = y +-else +-KERNEL_DEFENSES_STACK_PROTECTION = n +-endif ++KERNEL_DEFENSES_STACK_PROTECTION ?= n + + #---------------------------------------------------------------------- + # ADF paths diff --git a/package/qat/firmware/quickassist-c3xxx/patches/0002-remove-host-include-paths.patch b/package/qat/firmware/quickassist-c3xxx/patches/0002-remove-host-include-paths.patch new file mode 100644 index 000000000..177d15fdb --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/patches/0002-remove-host-include-paths.patch @@ -0,0 +1,14 @@ +Index: quickassist-c3xxx-1.7.L.4.13.0-00009/quickassist/build_system/build_files/env_files/linux_2.6_user_space.mk +=================================================================== +--- quickassist-c3xxx-1.7.L.4.13.0-00009.orig/quickassist/build_system/build_files/env_files/linux_2.6_user_space.mk ++++ quickassist-c3xxx-1.7.L.4.13.0-00009/quickassist/build_system/build_files/env_files/linux_2.6_user_space.mk +@@ -46,8 +46,7 @@ + # + #------------------------------------------------------------- + +-INCLUDES+=-I/usr/include \ +- -I$(API_DIR) \ ++INCLUDES+=-I$(API_DIR) \ + -I$(ADF_CMN_DIR) \ + -I$(OSAL_DIR)/include \ + -I$(OSAL_DIR)/src/linux/user_space/include diff --git a/package/qat/kernel/kmod-crypto-crc32-pclmul/Makefile b/package/qat/kernel/kmod-crypto-crc32-pclmul/Makefile new file mode 100644 index 000000000..fcca68a22 --- /dev/null +++ b/package/qat/kernel/kmod-crypto-crc32-pclmul/Makefile @@ -0,0 +1,49 @@ + +# +# Copyright (C) 2019 OpenWrt.org and dl12345@github.com +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +KMOD_NAME:=crypto-crc32-pclmul +PKG_NAME:=kmod-$(KMOD_NAME) +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=dl12345 +PKG_LICENSE:=GPL v3 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +CRYPTO_MENU:=Cryptographic API modules + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define KernelPackage/crypto-crc32-pclmul + SUBMENU:=$(CRYPTO_MENU) + TITLE:=CRC32 hardware acceleration (PCLMULDQ) + DEPENDS:=+kmod-crypto-hash +kmod-crypto-crc32 @TARGET_x86_64 + KCONFIG:=CONFIG_CRYPTO_CRC32_PCLMUL + FILES:=$(LINUX_DIR)/arch/x86/crypto/crc32-pclmul.ko + AUTOLOAD:=$(call AutoLoad,09,crc32-pclmul) +endef + +define KernelPackage/$(KMOD_NAME)/description + From Intel Westmere and AMD Bulldozer processor with SSE4.2 and PCLMULQDQ supported, the processor will support CRC32 PCLMULQDQ + implementation using hardware accelerated PCLMULQDQ instruction. This option will create 'crc32-pclmul' module, which will enable + any routine to use the CRC-32-IEEE 802.3 checksum and gain better performance as compared with the table implementation +endef + +$(eval $(call KernelPackage,$(KMOD_NAME))) + diff --git a/package/qat/kernel/kmod-crypto-crc32c-intel/Makefile b/package/qat/kernel/kmod-crypto-crc32c-intel/Makefile new file mode 100644 index 000000000..a3d2700ce --- /dev/null +++ b/package/qat/kernel/kmod-crypto-crc32c-intel/Makefile @@ -0,0 +1,48 @@ +# +# Copyright (C) 2019 OpenWrt.org and dl12345@github.com +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +KMOD_NAME:=crypto-crc32c-intel +PKG_NAME:=kmod-$(KMOD_NAME) +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=dl12345 +PKG_LICENSE:=GPL v3 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +CRYPTO_MENU:=Cryptographic API modules + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define KernelPackage/crypto-crc32c-intel + SUBMENU:=$(CRYPTO_MENU) + TITLE:=CRC32c hardware acceleration (SSE4.2) + DEPENDS:=+kmod-crypto-hash @TARGET_x86_64 + KCONFIG:=CONFIG_CRYPTO_CRC32C_INTEL + FILES:=$(LINUX_DIR)/arch/x86/crypto/crc32c-intel.ko + AUTOLOAD:=$(call AutoLoad,09,crc32-intel) +endef + +define KernelPackage/$(KMOD_NAME)/description + In Intel processor with SSE4.2 supported, the processor will support CRC32C implementation using hardware accelerated CRC32 instruction. + This option will create 'crc32c-intel' module, which will enable any routine to use the hardware accelerated CRC32 instruction + Module will be crc32c-intel +endef + +$(eval $(call KernelPackage,$(KMOD_NAME))) + diff --git a/package/qat/kernel/kmod-crypto-crct10dif-pclmu/Makefile b/package/qat/kernel/kmod-crypto-crct10dif-pclmu/Makefile new file mode 100644 index 000000000..f6a237f63 --- /dev/null +++ b/package/qat/kernel/kmod-crypto-crct10dif-pclmu/Makefile @@ -0,0 +1,47 @@ +# +# Copyright (C) 2019 OpenWrt.org and dl12345@github.com +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +KMOD_NAME:=crypto-crct10dif-pclmu +PKG_NAME:=kmod-$(KMOD_NAME) +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=dl12345 +PKG_LICENSE:=GPL v3 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +CRYPTO_MENU:=Cryptographic API modules + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define KernelPackage/$(KMOD_NAME) + SUBMENU:=$(CRYPTO_MENU) + TITLE:=CRCT10DIF hardware acceleration + DEPENDS:=+kmod-crypto-hash @TARGET_x86_64 + KCONFIG:=CONFIG_CRYPTO_CRCT10DIF_PCLMUL + FILES:=$(LINUX_DIR)/arch/x86/crypto/crct10dif-pclmul.ko + AUTOLOAD:=$(call AutoLoad,09,crct10dif-pclmul) +endef + +define KernelPackage/$(KMOD_NAME)/description + CRC T10 Data Integrity Field computation is being cast as a crypto transform. + This allows for faster crc t10 diff transforms to be used if they are available. +endef + +$(eval $(call KernelPackage,$(KMOD_NAME))) + diff --git a/package/qat/kernel/kmod-crypto-ghash-clmulni/Makefile b/package/qat/kernel/kmod-crypto-ghash-clmulni/Makefile new file mode 100644 index 000000000..02d7371be --- /dev/null +++ b/package/qat/kernel/kmod-crypto-ghash-clmulni/Makefile @@ -0,0 +1,46 @@ +# +# Copyright (C) 2019 OpenWrt.org and dl12345@github.com +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +KMOD_NAME:=crypto-ghash-clmulni +PKG_NAME:=kmod-$(KMOD_NAME) +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=dl12345 +PKG_LICENSE:=GPL v3 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +CRYPTO_MENU:=Cryptographic API modules + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define KernelPackage/crypto-ghash-clmulni + SUBMENU:=$(CRYPTO_MENU) + TITLE:=GHASH digest hardware acceleration + DEPENDS:=+kmod-crypto-ghash @TARGET_x86_64 + KCONFIG:=CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL + FILES:=$(LINUX_DIR)/arch/x86/crypto/ghash-clmulni-intel.ko + AUTOLOAD:=$(call AutoLoad,09,ghash-clmulni-intel) +endef + +define KernelPackage/$(KMOD_NAME)/description + GHASH is message digest algorithm for GCM (Galois/Counter Mode). The implementation is accelerated by CLMUL-NI of Intel. +endef + +$(eval $(call KernelPackage,$(KMOD_NAME))) + diff --git a/package/qat/kernel/kmod-crypto-misc-cxxxx/Makefile b/package/qat/kernel/kmod-crypto-misc-cxxxx/Makefile new file mode 100644 index 000000000..7e453e06d --- /dev/null +++ b/package/qat/kernel/kmod-crypto-misc-cxxxx/Makefile @@ -0,0 +1,63 @@ +# +# Copyright (C) 2019 OpenWrt.org and dl12345@github.com +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +KMOD_NAME:=crypto-misc-cxxxx +PKG_NAME:=kmod-$(KMOD_NAME) +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=dl12345 +PKG_LICENSE:=GPL v3 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +CRYPTO_MENU:=Cryptographic API modules + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define KernelPackage/crypto-misc-cxxxx + SUBMENU:=$(CRYPTO_MENU) + HIDDEN:=1 + TITLE:=crypto-misc-cxxxx + DEPENDS:=kmod-crypto-misc @(TARGET_x86_c2xxx||TARGET_x86_c3xxx) + DEFAULT:=y if ((TARGET_x86_c2xxx||TARGET_x86_c3xxx) && PACKAGE_kmod-crypto-misc) + FILES:= \ + $(LINUX_DIR)/arch/x86/crypto/camellia-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/blowfish-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/twofish-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/twofish-x86_64-3way.ko \ + $(LINUX_DIR)/arch/x86/crypto/serpent-sse2-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/camellia-aesni-avx-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/cast5-avx-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/cast6-avx-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/twofish-avx-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/serpent-avx-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/camellia-aesni-avx2.ko \ + $(LINUX_DIR)/arch/x86/crypto/serpent-avx2.ko \ + $(LINUX_DIR)/crypto/ablk_helper.ko@lt4.17 + AUTOLOAD+= $(call AutoLoad,10,camellia-x86_64 \ + camellia-aesni-avx-x86_64 camellia-aesni-avx2 cast5-avx-x86_64 \ + cast6-avx-x86_64 twofish-x86_64 twofish-x86_64-3way \ + twofish-avx-x86_64 blowfish-x86_64 serpent-avx-x86_64 serpent-avx2) +endef + +define KernelPackage/$(KMOD_NAME)/description + Camellia, Camellia-AESNI, Blowfish, Twofish, Serpent, Serpent SSE2, Serpent AVX2, Cast5, Cast6 +endef + +$(eval $(call KernelPackage,$(KMOD_NAME))) + diff --git a/package/qat/kernel/kmod-crypto-sha-cxxxx/Makefile b/package/qat/kernel/kmod-crypto-sha-cxxxx/Makefile new file mode 100644 index 000000000..6c6547fd2 --- /dev/null +++ b/package/qat/kernel/kmod-crypto-sha-cxxxx/Makefile @@ -0,0 +1,66 @@ +# +# Copyright (C) 2019 OpenWrt.org and dl12345@github.com +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +KMOD_NAME:=crypto-sha-cxxxx +PKG_NAME:=kmod-$(KMOD_NAME) +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=dl12345 +PKG_LICENSE:=GPL v3 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +CRYPTO_MENU:=Cryptographic API modules +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define KernelPackage/crypto-sha1-cxxxx + SUBMENU:=$(CRYPTO_MENU) + TITLE:=SHA1 x86_64 versions for C2000/C3000 target + HIDDEN:=1 + DEPENDS:=kmod-crypto-sha1 @(TARGET_x86_c2xxx||TARGET_x86_c3xxx) + DEFAULT:=y if ((TARGET_x86_c2xxx||TARGET_x86_c3xxx) && PACKAGE_kmod-crypto-sha1) + FILES:=$(LINUX_DIR)/arch/x86/crypto/sha1-ssse3.ko + AUTOLOAD+=$(call AutoLoad,09,sha1-ssse3) +endef + +define KernelPackage/crypto-sha256-cxxxx + SUBMENU:=$(CRYPTO_MENU) + TITLE:=SHA256 x86_64 versions for C2000/C3000 target + HIDDEN:=1 + DEPENDS:=kmod-crypto-sha256 @(TARGET_x86_c2xxx||TARGET_x86_c3xxx) + DEFAULT:=y if ((TARGET_x86_c2xxx||TARGET_x86_c3xxx) && PACKAGE_kmod-crypto-sha256) + FILES:=$(LINUX_DIR)/arch/x86/crypto/sha256-ssse3.ko + AUTOLOAD+=$(call AutoLoad,09,sha256-ssse3) +endef + +define KernelPackage/crypto-sha512-cxxxx + SUBMENU:=$(CRYPTO_MENU) + TITLE:=SHA512 x86_64 versions for C2000/C3000 target + HIDDEN:=1 + DEPENDS:=kmod-crypto-sha512 @(TARGET_x86_c2xxx||TARGET_x86_c3xxx) + DEFAULT:=y if ((TARGET_x86_c2xxx||TARGET_x86_c3xxx) && PACKAGE_kmod-crypto-sha512) + FILES:=$(LINUX_DIR)/arch/x86/crypto/sha512-ssse3.ko + AUTOLOAD+=$(call AutoLoad,09,sha512-ssse3) +endef + +$(eval $(call KernelPackage,crypto-sha1-cxxxx)) +$(eval $(call KernelPackage,crypto-sha256-cxxxx)) +$(eval $(call KernelPackage,crypto-sha512-cxxxx)) + diff --git a/package/qat/libs/eudev/Config.in b/package/qat/libs/eudev/Config.in new file mode 100644 index 000000000..900741ebf --- /dev/null +++ b/package/qat/libs/eudev/Config.in @@ -0,0 +1,69 @@ +# udev package config + +menu "Configuration" + depends on PACKAGE_eudev + +config EUDEV_EXTRA_ata_id + bool "Install eudev ata_id callout" + default y + help + ata_id - udev callout to read product/serial number + from ATA drives + +config EUDEV_EXTRA_blkid + bool "Use blkid to identify block devices" + default y + help + blkid - make use of libblkid to identify block devices + +config EUDEV_EXTRA_cdrom_id + bool "Install eudev cdrom_id callout" + default y + help + cdrom_id - udev callout to determine the capabilities + of optical drives and media + +config EUDEV_EXTRA_collect + bool "Install eudev collect" + default n + help + Adds ID to the list governed by + +config EUDEV_EXTRA_input_id + bool "Install input_id callout" + default y + help + input_id - udev callout to classify input devices + +config EUDEV_EXTRA_kmod + bool "Use kmod for loading kernel modules" + default n + help + kmod - make use of kmod to load kernel modules on demand + +config EUDEV_EXTRA_mtd_probe + bool "Install mtd_probe callout" + default y + help + mtd_probe - udev callout to probe mtd devices + +config EUDEV_EXTRA_rule_generator + bool "Install (legacy) eudev rule_generator" + default n + help + Install (legacy) eudev rule_generator + +config EUDEV_EXTRA_scsi_id + bool "Install eudev scsi_id callout" + default y + help + scsi_id - retrieve and generate a unique SCSI identifier + +config EUDEV_EXTRA_v4l_id + bool "Install eudev v4l_id callout" + default y + help + v4l_id - udev callout to identify Video4Linux devices + + +endmenu diff --git a/package/qat/libs/eudev/Makefile b/package/qat/libs/eudev/Makefile new file mode 100644 index 000000000..21acbfba9 --- /dev/null +++ b/package/qat/libs/eudev/Makefile @@ -0,0 +1,88 @@ +# +# Copyright (C) 2006-2008 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=eudev +PKG_VERSION:=3.2.10 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://dev.gentoo.org/~blueness/eudev/ +PKG_HASH:=87bb028d470fd1b85169349b44c55d5b733733dc2d50ddf1196e026725ead034 +PKG_LICENSE:=GPL-2.0 + +include $(INCLUDE_DIR)/package.mk + +PKG_BUILD_DEPENDS:=gperf/host +PKG_FIXUP:=autoreconf +PKG_INSTALL=1 + +define Package/libeudev + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Dynamic device management subsystem + URL:=https://wiki.gentoo.org/wiki/Project:Eudev + MAINTAINER:=Ian Cooper + PROVIDES:=libudev + CONFLICTS:=libudev-zero udev +endef + +define Package/eudev + SECTION:=Libs + CATEGORY:=Libraries + TITLE:=Dynamic device management subsystem + URL:=https://wiki.gentoo.org/wiki/Project:Eudev + MAINTAINER:=Ian Cooper + MENU:=1 + DEPENDS:=+EUDEV_EXTRA_blkid:libblkid +EUDEV_EXTRA_kmod:libkmod +librt +libeudev +endef + +define Package/eudev/description +Eudev is the Gentoo Linux port of udev. This implementation installs only the libraries +and a udevmonitor binary. This allows packages dependent on libudev to be compiled and +run on OpenWrt. The udevmonitor binary can be used to see what events are tiggered so +that an appropriate hotplug handler script can be installed. +endef + +define Package/eudev/config + source "$(SOURCE)/Config.in" +endef + +CONFIGURE_ARGS += \ + --prefix=/usr --exec-prefix= --sysconfdir=/etc \ + --libexecdir=/lib/udev --sbindir=/sbin \ + --disable-hwdb --disable-introspection --disable-manpages \ + --disable-selinux \ + $(if $(CONFIG_EUDEV_EXTRA_blkid),--enable-blkid,--disable-blkid) \ + $(if $(CONFIG_EUDEV_EXTRA_kmod),--enable-kmod,--disable-kmod) + + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include + $(CP) $(PKG_INSTALL_DIR)/usr/include/libudev.h $(1)/usr/include + $(INSTALL_DIR) $(1)/usr/share/pkgconfig + $(CP) $(PKG_INSTALL_DIR)/usr/share/pkgconfig/udev.pc $(1)/usr/share/pkgconfig + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/lib/libudev.so* $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/lib/libudev.a $(1)/usr/lib + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(CP) $(PKG_INSTALL_DIR)/lib/pkgconfig/libudev.pc $(1)/usr/lib/pkgconfig +endef + +define Package/libeudev/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/lib/libudev.so* $(1)/usr/lib +endef + +define Package/eudev/install + $(INSTALL_DIR) $(1)/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/udevadm $(1)/sbin/udevadm +endef + +$(eval $(call BuildPackage,eudev)) +$(eval $(call BuildPackage,libeudev)) diff --git a/package/qat/libs/eudev/patches/0001-mtd_probe-uses-stdint_h.patch b/package/qat/libs/eudev/patches/0001-mtd_probe-uses-stdint_h.patch new file mode 100644 index 000000000..deac91589 --- /dev/null +++ b/package/qat/libs/eudev/patches/0001-mtd_probe-uses-stdint_h.patch @@ -0,0 +1,12 @@ +Index: eudev-3.2.9/src/mtd_probe/mtd_probe.h +=================================================================== +--- eudev-3.2.9.orig/src/mtd_probe/mtd_probe.h ++++ eudev-3.2.9/src/mtd_probe/mtd_probe.h +@@ -20,6 +20,7 @@ + #pragma once + + #include ++#include + + #include "macro.h" + diff --git a/package/qat/libs/eudev/patches/0002-udevadm-cutdown.patch b/package/qat/libs/eudev/patches/0002-udevadm-cutdown.patch new file mode 100644 index 000000000..e64670007 --- /dev/null +++ b/package/qat/libs/eudev/patches/0002-udevadm-cutdown.patch @@ -0,0 +1,18 @@ +Index: eudev-3.2.9/src/udev/udevadm.c +=================================================================== +--- eudev-3.2.9.orig/src/udev/udevadm.c ++++ eudev-3.2.9/src/udev/udevadm.c +@@ -45,13 +45,7 @@ static const struct udevadm_cmd udevadm_ + + static const struct udevadm_cmd *udevadm_cmds[] = { + &udevadm_info, +- &udevadm_trigger, +- &udevadm_settle, +- &udevadm_control, + &udevadm_monitor, +- &udevadm_hwdb, +- &udevadm_test, +- &udevadm_test_builtin, + &udevadm_version, + &udevadm_help, + }; diff --git a/package/qat/libs/openssl-qat/Config.in b/package/qat/libs/openssl-qat/Config.in new file mode 100644 index 000000000..e3bd39381 --- /dev/null +++ b/package/qat/libs/openssl-qat/Config.in @@ -0,0 +1,160 @@ +menu "Configuration" + depends on TARGET_x86_64 + + choice + prompt "Platform" + default QAT_NONE + config QAT_NONE + bool "None (Default)" + config QAT_C2XXX + bool "c2xxx - Rangeley" + depends on LINUX_4_14 + select PACKAGE_quickassist-c2xxx + select PACKAGE_kmod-crypto-qat-c2xxx + select PACKAGE_kmod-crypto-qat-c2xxx-usdm + config QAT_C3XXX + bool "c3xxx - Denverton" + select PACKAGE_quickassist-c3xxx + select PACKAGE_kmod-crypto-qat-c3xxx + select PACKAGE_kmod-crypto-qat-common + select PACKAGE_kmod-crypto-qat-usdm + + endchoice + + config QAT_ENGINE_DISABLE_RSA + bool + default n + prompt "Disable QAT RSA offload" + + config QAT_ENGINE_DISABLE_DSA + bool + default n + prompt "Disable QAT DSA offload" + + config QAT_ENGINE_DISABLE_DH + bool + default n + prompt "Disable QAT DH offload" + + config QAT_ENGINE_DISABLE_EDSA + bool + default n + prompt "Disable QAT ECDSA offload" + + config QAT_ENGINE_DISABLE_CIPHERS + bool + default y + prompt "Disable QAT chained cipher offload" + help + Offload of chained ciphers performs significantly worse than CPU + based chained ciphers. Strongly recommended to keep this disabled + + config QAT_ENGINE_DISABLE_HKDF + bool + default y + prompt "Disable QAT HKDF offload" + help + Disable QAT HKDF offload + + config QAT_ENGINE_ENABLE_GCM_CIPHERS + bool + default n + prompt "Enable QAT GCM offload" + help + Enable QAT GCM offload + + config QAT_ENGINE_ENABLE_SMALL_PACKET + bool + default n + prompt "Enable offload of small packet cipher operations" + help + This is generally a bad idea from a performance point of view since + there is a penalty for transfer of the data across the pci bus to the + accelerator that makes it faster for small packet operations using + only cpu resources and not QAT offloading (generally < 4k bufsize) + + config QAT_ENGINE_ENABLE_WARNINGS + bool + default n + prompt "Enable warnings to aid in debugging" + help + WARNING: never leave on in a production environment as it may output + private key informtion to the logs and it may introduce side-channel + timing attack vulnerabilities + + config QAT_ENGINE_ENABLE_DEBUG + bool + default n + prompt "Enable debug output" + help + WARNING: never leave on in a production environment as it may output + private key informtion to the logs and it may introduce side-channel + timing attack vulnerabilities + + config QAT_ENGINE_ENABLE_QAT_MEM_WARNINGS + bool + default n + prompt "Enable warnings from the userspace memory management code" + help + WARNING: This option should never be left on in a production + environment as it may introduce side channel timing attack + vulnerabilities + + config QAT_ENGINE_ENABLE_MEM_DEBUG + bool + default n + prompt "Enable debug output from userspace memory management (very verbose)" + help + This will also enable the QAT_MEM warning messages. This option + produces quite verbose output hence why it is separate to the + standard debug. + + WARNING: This option should never be enabled in a production environment + as it may output private key information to the console/logs and may + also introduce side channel timing attack vulnerabilities + + config QAT_ENGINE_ENABLE_MULTITHREAD + bool + default n + prompt "Optimize for multi-threaded use" + help + This alternative method will give improved performance in a + multi-threaded environment by making the slab pools thread + local to avoid locking between threads. Although this can + give better performance there are several drawbacks such as + the memory slabs will be utilized less efficiently, and you + cannot allocate in one thread and free in another thread. + Running in this mode DOES NOT support processes that fork + + config QAT_ENGINE_DISABLE_LENSTRA + bool + default n + prompt "Disable protection against Lenstra attack (CVE-2017-5681)" + help + The RSA-CRT implementation in the Intel(R) QAT OpenSSL* Engine for + OpenSSL* versions prior to v0.5.19 may allow remote attackers to + obtain private RSA keys by conducting a Lenstra side-channel attack. + From version v0.5.19 onward, protection against this form of attack + is effected by performing a Verify/Encrypt operation after the Sign/Decrypt + operation, and if a failure is detected then re-running the Sign/Decrypt + operation using the CPU. However, future releases of Intel(R) QAT + driver code or firmware may effect this protection instead, in which + case the Intel(R) QAT OpenSSL* Engine code-based protection would no + longer be required and this configuration option should then be selected. + + config QAT_ENGINE_DISABLE_AUTOINIT_ONFORK + bool + default y + prompt "Disable auto engine init on fork" + help + Disable the engine from being initialized automatically following a + fork operation. This is useful in a situation where you want to tightly + control how many instances are being used for processes. For instance if an + application forks to start a process that does not utilize QAT currently + the default behaviour is for the engine to still automatically get started + in the child using up an engine instance. After using this flag either the + engine needs to be initialized manually using the engine message: + INIT_ENGINE or will automatically get initialized on the first QAT crypto + operation. + +endmenu diff --git a/package/qat/libs/openssl-qat/Makefile b/package/qat/libs/openssl-qat/Makefile new file mode 100644 index 000000000..e9b989840 --- /dev/null +++ b/package/qat/libs/openssl-qat/Makefile @@ -0,0 +1,84 @@ +# +# Copyright (C) Ian Cooper +# +# This is free software, licensed under the GNU General Public License v3. +# +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=openssl-qat +PKG_VERSION:=0.6.12 +PKG_RELEASE:=1 + +PKG_SOURCE:=v${PKG_VERSION}.tar.gz +PKG_SOURCE_URL:=https://github.com/intel/QAT_Engine/archive/refs/tags/ +PKG_HASH:=skip + +PKG_BUILD_DIR:=$(BUILD_DIR)/QAT_Engine-$(PKG_VERSION) +PKG_BUILD_DEPENDS:=openssl +PKG_FIXUP:=autoreconf +PKG_REMOVE_FILES:=autogen.sh + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/kernel.mk + +define Package/openssl-qat + SECTION:=libs + CATEGORY:=Libraries + SUBMENU:=SSL + TITLE:=Intel Quick Assist OpenSSL Engine + URL:=https://github.com/intel/QAT_Engine.git + DEPENDS:= \ + @TARGET_x86_64 \ + +libopenssl \ + +(TARGET_x86_64&&QAT_C2XXX):quickassist-c2xxx \ + +(TARGET_x86_64&&QAT_C3XXX):quickassist-c3xxx +endef + +define Package/openssl-qat/description + Intel Quick Assist hardware acceleration engine for OpenSSL +endef + +define Package/openssl-qat/config + source "$(SOURCE)/Config.in" +endef + +#CONFIGURE_ARGS += --with-openssl_install_dir=$(PKG_INSTALL_DIR)/usr +CONFIGURE_ARGS += --prefix=$(PKG_INSTALL_DIR) + +CONFIGURE_ARGS += $(if $(CONFIG_QAT_C3XXX) ,--with-qat_hw_dir=$(KERNEL_BUILD_DIR)/quickassist-c3xxx-1.7) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_C2XXX) ,--with-qat_hw_dir=$(KERNEL_BUILD_DIR)/quickassist-c2xxx-1.5) + +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_RSA) ,--disable-qat_rsa) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_DSA) ,--disable-qat_dsa) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_DH) ,--disable-qat_dh) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_ECDSA) ,--disable-qat_ecdsa) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_CIPHERS) ,--disable-qat_ciphers) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_PRF) ,--disable-qat_prf) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_HKDF) ,--disable-qat_hkdf) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_ENABLE_GCM_CIPHERS) ,--enable-qat_gcm) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_ENABLE_SMALL_PACKET) ,--enable-qat_small_pkt_offload) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_ENABLE_WARNINGS) ,--enable-qat_warnings) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_ENABLE_DEBUG) ,--enable-qat_debug) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_ENABLE_QAT_MEM_WARNINGS) ,--enable-qat_mem_warnings) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_ENABLE_MEM_DEBUG) ,--enable-qat_mem_debug) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_ENABLE_MULTITHREAD) ,--enable-multi_thread) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_LENSTRA) ,--disable-qat_lenstra_protection) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_AUTOINIT_ONFORK) ,--disable-qat_auto_engine_init_on_fork) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_C2XXX) ,--enable-qat16_driver) + +MAKE_VARS += \ + CROSS_COMPILE="$(KERNEL_CROSS)" \ + KERNEL_SOURCE_ROOT="$(LINUX_DIR)" \ + PATH_AUTOCNF="include/generated/autoconf.h" \ + WITH_ICP_TARGET="1" + +define Package/openssl-qat/install + $(INSTALL_DIR) $(1)/usr/lib/engines-1.1 + $(INSTALL_DIR) $(1)/usr/share/quickassist/QAT_Engine/config + $(CP) $(PKG_BUILD_DIR)/.libs/qatengine.so $(1)/usr/lib/engines-1.1 + $(CP) $(PKG_BUILD_DIR)/qatengine.la $(1)/usr/lib/engines-1.1 + $(CP) $(PKG_BUILD_DIR)/qat/config/c3xxx $(1)/usr/share/quickassist/QAT_Engine/config +endef + +$(eval $(call BuildPackage,openssl-qat)) diff --git a/package/qat/libs/openssl-qat/patches/0001-remove-FORTIFY_SOURCE.patch b/package/qat/libs/openssl-qat/patches/0001-remove-FORTIFY_SOURCE.patch new file mode 100644 index 000000000..216451402 --- /dev/null +++ b/package/qat/libs/openssl-qat/patches/0001-remove-FORTIFY_SOURCE.patch @@ -0,0 +1,33 @@ +From 15529dee574c62004a204018de66249335a20cf2 Mon Sep 17 00:00:00 2001 +From: W_Y_CPP <383152993@qq.com> +Date: Sun, 24 Apr 2022 04:37:14 -0400 +Subject: [PATCH] remove-FORTIFY_SOURCE + +--- + configure.ac | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/configure.ac b/configure.ac +index d6e43df74..b12492389 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -742,13 +742,13 @@ case "$host_os" in + *linux*) + if test "`cc --version | head -1 | awk '{print $3>=4.9}' 2>/dev/null`" = "1" + then +- AC_SUBST([cflags], ["-shared -fPIC -Wall -Wformat -Wformat-security -O2 -D_FORTIFY_SOURCE=2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector-strong -fno-strict-overflow"]) ++ AC_SUBST([cflags], ["-shared -fPIC -Wall -Wformat -Wformat-security -O2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector-strong -fno-strict-overflow"]) + else +- AC_SUBST([cflags], ["-shared -fPIC -Wall -Wformat -Wformat-security -O2 -D_FORTIFY_SOURCE=2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector -fno-strict-overflow"]) ++ AC_SUBST([cflags], ["-shared -fPIC -Wall -Wformat -Wformat-security -O2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector -fno-strict-overflow"]) + fi + ;; + *freebsd*) +- AC_SUBST([cflags], ["-shared -fPIC -Wall -Wformat -Wformat-security -O2 -D_FORTIFY_SOURCE=2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector-strong"]) ++ AC_SUBST([cflags], ["-shared -fPIC -Wall -Wformat -Wformat-security -O2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector-strong"]) + ;; + *) ;; + esac +-- +2.17.1 + diff --git a/package/qat/libs/openssl-qat/patches/0001-remove-check-icp_sal_versions.patch b/package/qat/libs/openssl-qat/patches/0001-remove-check-icp_sal_versions.patch new file mode 100644 index 000000000..e833f5939 --- /dev/null +++ b/package/qat/libs/openssl-qat/patches/0001-remove-check-icp_sal_versions.patch @@ -0,0 +1,26 @@ +From 3d9af59ddb472c814fb99ae1fab85030560d2fc6 Mon Sep 17 00:00:00 2001 +From: W_Y_CPP <383152993@qq.com> +Date: Sun, 24 Apr 2022 05:50:46 -0400 +Subject: [PATCH] remove check icp_sal_versions + +--- + configure.ac | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/configure.ac b/configure.ac +index d6e43df74..2d981ddcc 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -252,9 +252,6 @@ AC_SUBST(enable_qat_auto_engine_init_on_fork) + #Default library name is qatengine + AC_SUBST([LIBQATNAME], "qatengine") + +-AC_CHECK_FILE(${qat_hw_dir_prefix}/include/qat/icp_sal_versions.h, +- [with_icp_sal_versions_h=yes], +- [with_icp_sal_versions_h=no]) + if test "x$with_icp_sal_versions_h" = "xyes" -a "x$enable_qat_sw" = "x" + then + if test `grep "define SAL_INFO2_DRIVER_SW_VERSION_TYPE \"in-tree\"" ${qat_hw_dir_prefix}/include/qat/icp_sal_versions.h | wc -l` = "1" +-- +2.17.1 + diff --git a/package/qat/libs/qatzip/Makefile b/package/qat/libs/qatzip/Makefile new file mode 100644 index 000000000..a08755b19 --- /dev/null +++ b/package/qat/libs/qatzip/Makefile @@ -0,0 +1,108 @@ +# +# Copyright (C) DL +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=qatzip +PKG_VERSION:=1 +PKG_RELEASE:=1 + +PKG_SOURCE_URL:=https://github.com/intel/QATzip +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2020-05-15 +PKG_SOURCE_VERSION:=5abaaf546a479350ada023115c6e3d499db2b363 +PKG_MIRROR_HASH:=17ff33161e7a6b513f90050fb747e0a6f0a74ea3e4e3b1dc10b18e5540adbe9a + +PKG_BUILD_DEPENDS:=openssl +PKG_FIXUP:=autoreconf + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/kernel.mk + +define Package/libqatzip + SECTION:=libs + CATEGORY:=Libraries + SUBMENU:=Compression + TITLE:=Intel Quick Assist QATzip Compression Library + URL:=https://github.com/intel/QATzip + DEPENDS:= \ + @TARGET_x86_64 \ + +zlib \ + +openssl-qat +endef + +define Package/libqatzip/description + Intel Quick Assist userspace compression library +endef + +define Package/qzip + SECTION:=utils + CATEGORY:=Utilities + SUBMENU:=Compression + TITLE:=Intel Quick Assist qzip compression utility + URL:=https://github.com/intel/QATzip + DEPENDS:= \ + @TARGET_x86_64 \ + +libqatzip +endef + +define Package/qzip/description + Intel Quick Assist file compression utility +endef + +PKG_BUILD_DEPENDS += $(if $(CONFIG_QAT_C2XXX),quickassist-c2xxx,quickassist-c3xxx) +QAT_DIR=$(KERNEL_BUILD_DIR)/$(if $(CONFIG_QAT_C2XXX),quickassist-c2xxx-1.5,quickassist-c3xxx-1.7)/quickassist + +TARGET_CFLAGS += \ + -I$(QAT_DIR)/include \ + -I$(QAT_DIR)/include/dc \ + -I$(QAT_DIR)/lookaside/access_layer/include \ + -I$(QAT_DIR)/utilities/libusdm_drv \ + -I$(PKG_BUILD_DIR)/include \ + -I$(PKG_BUILD_DIR)/src \ + -DADF_PCI_API \ + -fPIC + +TARGET_LDFLAGS += \ + -L$(QAT_DIR)/build + +MAKE_VARS += \ + QATZIP_LIB_STATIC="libqatzip.a" \ + QATZIP_LIB_SHARED="libqatzip.so" \ + QATZIP_LIB_D="$(PKG_BUILD_DIR)/src" \ + LIBADD="-lqat_s -lusdm_drv_s -lz -lpthread -ludev -lssl" \ + VER="1.0.1" \ + VER_M="1" \ + LN_S="ln -s" + +define Build/Configure +endef + +define Build/Compile + $(call Build/Compile/Default, -C src libqatzip.so) + $(call Build/Compile/Default, -C src libqatzip.a) + $(call Build/Compile/Default, -C utils qzip) +endef + +define Package/InstallDev + $(INSTALL_DIR) $(1)/usr/lib + $(INSTALL_DIR) $(1)/usr/include + $(CP) $(PKG_BUILD_DIR)/src/lib*.{a,so*} $(1)/usr/lib/ +endef + +define Package/libqatzip/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/src/lib*.so* $(1)/usr/lib/ +endef + +define Package/qzip/install + $(INSTALL_DIR) $(1)/usr/bin + $(CP) $(PKG_BUILD_DIR)/utils/qzip $(1)/usr/bin/qzip +endef + +$(eval $(call BuildPackage,libqatzip)) +$(eval $(call BuildPackage,qzip)) diff --git a/package/qat/libs/qatzip/patches/0001-musl-bits-types.patch b/package/qat/libs/qatzip/patches/0001-musl-bits-types.patch new file mode 100644 index 000000000..dbaa66de4 --- /dev/null +++ b/package/qat/libs/qatzip/patches/0001-musl-bits-types.patch @@ -0,0 +1,14 @@ +Index: qatzip-1/src/qatzip.c +=================================================================== +--- qatzip-1.orig/src/qatzip.c ++++ qatzip-1/src/qatzip.c +@@ -40,7 +40,9 @@ + #include + #include + #include ++#if defined(__linux__) && defined(__GLIBC__) + #include ++#endif + #include + #include + #include diff --git a/package/qat/libs/qatzip/patches/0002-musl-reopen-stdout.patch b/package/qat/libs/qatzip/patches/0002-musl-reopen-stdout.patch new file mode 100644 index 000000000..7011acb8a --- /dev/null +++ b/package/qat/libs/qatzip/patches/0002-musl-reopen-stdout.patch @@ -0,0 +1,14 @@ +Index: qatzip-1/utils/qzip.c +=================================================================== +--- qatzip-1.orig/utils/qzip.c ++++ qatzip-1/utils/qzip.c +@@ -776,7 +776,9 @@ int main(int argc, char **argv) + printf("For help, type: qzip -h\n"); + } else { + stream_out = stdout; ++#ifdef __GLIBC___ + stdout = freopen(NULL, "w", stdout); ++#endif + processStream(&g_sess, stdin, stream_out, g_decompress == 0); + } + } else { diff --git a/package/qca/nss/qca-mcs/patches/101-revert-to-old-build-logic.patch b/package/qca/nss/qca-mcs/patches/101-revert-to-old-build-logic.patch deleted file mode 100644 index f35e78b5c..000000000 --- a/package/qca/nss/qca-mcs/patches/101-revert-to-old-build-logic.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/Makefile -+++ b/Makefile -@@ -32,7 +32,9 @@ ccflags-y += -I$(CURDIR) \ - -I$(KBUILDPATH)/include/asm \ - -I$(KBUILDPATH)/net/bridge - --ccflags-$(CONFIG_SUPPORT_MLD) += -DMC_SUPPORT_MLD -+ifeq ($(strip ${MC_SUPPORT_MLD}),1) -+ccflags-y+=-DMC_SUPPORT_MLD -+endif - - # Module extra compilation flags - ccflags-y += -Werror -Wall -g diff --git a/package/qca/nss/qca-nss-clients-64/Makefile b/package/qca/nss/qca-nss-clients-64/Makefile index 11abb99a7..153166872 100644 --- a/package/qca/nss/qca-nss-clients-64/Makefile +++ b/package/qca/nss/qca-nss-clients-64/Makefile @@ -17,7 +17,7 @@ define KernelPackage/qca-nss-drv-pppoe-64 CATEGORY:=Kernel modules SUBMENU:=Network Devices TITLE:=Kernel driver for NSS (connection manager) - PPPoE - DEPENDS:=@TARGET_ipq807x +kmod-qca-nss-drv-64 +kmod-ppp +kmod-pppoe + DEPENDS:=@(TARGET_ipq60xx||TARGET_ipq807x) +kmod-qca-nss-drv-64 +kmod-ppp +kmod-pppoe FILES:=$(PKG_BUILD_DIR)/pppoe/qca-nss-pppoe.ko AUTOLOAD:=$(call AutoLoad,51,qca-nss-pppoe) endef @@ -26,6 +26,34 @@ define KernelPackage/qca-nss-drv-pppoe-64/Description Kernel modules for NSS connection manager - Support for PPPoE endef +define KernelPackage/qca-nss-drv-bridge-mgr-64 + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS bridge manager + DEPENDS:=@(LINUX_5_10||LINUX_5_15) @(TARGET_ipq60xx||TARGET_ipq807x) +kmod-qca-nss-drv-64 +kmod-qca-nss-drv-vlan-mgr-64 + FILES:=$(PKG_BUILD_DIR)/bridge/qca-nss-bridge-mgr.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-bridge-mgr) +endef + +define KernelPackage/qca-nss-drv-bridge-mgr-64/Description +Kernel modules for NSS bridge manager +endef + +define KernelPackage/qca-nss-drv-vlan-mgr-64 + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS vlan manager + DEPENDS:=@(LINUX_5_10||LINUX_5_15) @(TARGET_ipq60xx||TARGET_ipq807x) +kmod-qca-nss-drv-64 + FILES:=$(PKG_BUILD_DIR)/vlan/qca-nss-vlan.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-vlan) +endef + +define KernelPackage/qca-nss-drv-vlan-mgr-64/Description +Kernel modules for NSS vlan manager +endef + EXTRA_CFLAGS+= \ -I$(STAGING_DIR)/usr/include/qca-nss-drv \ -I$(STAGING_DIR)/usr/include/qca-nss-crypto \ @@ -39,6 +67,14 @@ ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-pppoe-64),) NSS_CLIENTS_MAKE_OPTS+=pppoe=y endif +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-bridge-mgr-64),) +NSS_CLIENTS_MAKE_OPTS+=bridge-mgr=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-vlan-mgr-64),) +NSS_CLIENTS_MAKE_OPTS+=vlan-mgr=y +endif + ifeq ($(CONFIG_TARGET_BOARD), "ipq807x") SOC="ipq807x_64" else ifeq ($(CONFIG_TARGET_BOARD), "ipq60xx") @@ -57,3 +93,5 @@ define Build/Compile endef $(eval $(call KernelPackage,qca-nss-drv-pppoe-64)) +$(eval $(call KernelPackage,qca-nss-drv-bridge-mgr-64)) +$(eval $(call KernelPackage,qca-nss-drv-vlan-mgr-64)) diff --git a/package/qca/nss/qca-nss-dp/patches/0006-NSS-DP-fix-of_get_mac_address.patch b/package/qca/nss/qca-nss-dp/patches/0006-NSS-DP-fix-of_get_mac_address.patch new file mode 100644 index 000000000..d4965716d --- /dev/null +++ b/package/qca/nss/qca-nss-dp/patches/0006-NSS-DP-fix-of_get_mac_address.patch @@ -0,0 +1,50 @@ +From cadeb62a42296563141d6954eec58e34ef86778d Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 13 Aug 2021 20:12:08 +0200 +Subject: [PATCH] NSS-DP: fix of_get_mac_address() + +Recently OpenWrt backported the updated of_get_mac_address() +function which returns and error code instead. + +So, patch the SSDK to use it and fix the compilation error. + +Signed-off-by: Robert Marko +--- + nss_dp_main.c | 13 ++++--------- + 1 file changed, 4 insertions(+), 9 deletions(-) + +diff --git a/nss_dp_main.c b/nss_dp_main.c +index 5580b13..28df280 100644 +--- a/nss_dp_main.c ++++ b/nss_dp_main.c +@@ -434,9 +434,10 @@ static int32_t nss_dp_of_get_pdata(struct device_node *np, + struct net_device *netdev, + struct gmac_hal_platform_data *hal_pdata) + { +- uint8_t *maddr; ++ u8 maddr[ETH_ALEN]; + struct nss_dp_dev *dp_priv; + struct resource memres_devtree = {0}; ++ int ret; + + dp_priv = netdev_priv(netdev); + +@@ -475,14 +476,8 @@ static int32_t nss_dp_of_get_pdata(struct device_node *np, + of_property_read_u32(np, "qcom,forced-speed", &dp_priv->forced_speed); + of_property_read_u32(np, "qcom,forced-duplex", &dp_priv->forced_duplex); + +- maddr = (uint8_t *)of_get_mac_address(np); +-#if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 4, 0)) +- if (IS_ERR((void *)maddr)) { +- maddr = NULL; +- } +-#endif +- +- if (maddr && is_valid_ether_addr(maddr)) { ++ ret = of_get_mac_address(np, maddr); ++ if (!ret && is_valid_ether_addr(maddr)) { + ether_addr_copy(netdev->dev_addr, maddr); + } else { + random_ether_addr(netdev->dev_addr); +-- +2.31.1 diff --git a/package/qca/nss/qca-nss-dp/patches/0007-NSS-DP-implement-ethernet-IOCTL-s.patch b/package/qca/nss/qca-nss-dp/patches/0007-NSS-DP-implement-ethernet-IOCTL-s.patch new file mode 100644 index 000000000..824f18634 --- /dev/null +++ b/package/qca/nss/qca-nss-dp/patches/0007-NSS-DP-implement-ethernet-IOCTL-s.patch @@ -0,0 +1,29 @@ +From 5da62ba19f554bf437752a44360fb5ae9f1a7f5e Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Tue, 8 Mar 2022 10:48:32 +0100 +Subject: [PATCH] NSS-DP: implement ethernet IOCTL-s + +Since kernel 5.15 ethernet/PHY related IOCTL-s have been split from the +generic IOCTL netdev op. +So, implement the new op instead of the generic one which is considered +for private IOCTL-s only now for 5.15+. + +Signed-off-by: Robert Marko +--- + nss_dp_main.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/nss_dp_main.c ++++ b/nss_dp_main.c +@@ -532,7 +532,11 @@ static const struct net_device_ops nss_d + .ndo_set_mac_address = nss_dp_set_mac_address, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = nss_dp_change_mtu, ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) + .ndo_do_ioctl = nss_dp_do_ioctl, ++#else ++ .ndo_eth_ioctl = nss_dp_do_ioctl, ++#endif + + #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) + .ndo_bridge_setlink = switchdev_port_bridge_setlink, diff --git a/package/qca/nss/qca-nss-dp/patches/0008-switchdev-remove-the-transaction-structure.patch b/package/qca/nss/qca-nss-dp/patches/0008-switchdev-remove-the-transaction-structure.patch new file mode 100644 index 000000000..220be961a --- /dev/null +++ b/package/qca/nss/qca-nss-dp/patches/0008-switchdev-remove-the-transaction-structure.patch @@ -0,0 +1,48 @@ +From c9afdcdd2642485a6476906be9da2e811090fc7a Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 18 Mar 2022 18:06:03 +0100 +Subject: [PATCH] switchdev: remove the transaction structure + +Since 5.12 there is no transaction structure anymore, so drop it for +5.12 and newer. + +Signed-off-by: Robert Marko +--- + nss_dp_switchdev.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/nss_dp_switchdev.c ++++ b/nss_dp_switchdev.c +@@ -279,13 +279,19 @@ void nss_dp_switchdev_setup(struct net_d + * Sets attributes + */ + static int nss_dp_port_attr_set(struct net_device *dev, ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)) + const struct switchdev_attr *attr, + struct switchdev_trans *trans) ++#else ++ const struct switchdev_attr *attr) ++#endif + { + struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(dev); + ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)) + if (switchdev_trans_ph_prepare(trans)) + return 0; ++#endif + + switch (attr->id) { + case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS: +@@ -309,8 +315,12 @@ static int nss_dp_switchdev_port_attr_se + { + int err; + ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)) + err = nss_dp_port_attr_set(netdev, port_attr_info->attr, + port_attr_info->trans); ++#else ++ err = nss_dp_port_attr_set(netdev, port_attr_info->attr); ++#endif + + port_attr_info->handled = true; + return notifier_from_errno(err); diff --git a/package/qca/nss/qca-nss-dp/patches/0009-switchdev-use-new-switchdev-flags.patch b/package/qca/nss/qca-nss-dp/patches/0009-switchdev-use-new-switchdev-flags.patch new file mode 100644 index 000000000..5635dd964 --- /dev/null +++ b/package/qca/nss/qca-nss-dp/patches/0009-switchdev-use-new-switchdev-flags.patch @@ -0,0 +1,54 @@ +From f95868d54301c0f54e968ec9d978c9caa02ee425 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 18 Mar 2022 18:24:18 +0100 +Subject: [PATCH] switchdev: use new switchdev flags + +Since kernel 5.12 switched utilizes a new way of setting the flags by +using a dedicated structure with flags and mask. + +So fix using kernels 5.12 and later. + +Signed-off-by: Robert Marko +--- + include/nss_dp_dev.h | 7 +++++++ + nss_dp_switchdev.c | 2 +- + 2 files changed, 8 insertions(+), 1 deletion(-) + +--- a/include/nss_dp_dev.h ++++ b/include/nss_dp_dev.h +@@ -24,6 +24,9 @@ + #include + #include + #include ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)) ++#include ++#endif + + #include "nss_dp_api_if.h" + #include "nss_dp_hal_if.h" +@@ -126,7 +129,11 @@ struct nss_dp_dev { + /* switchdev related attributes */ + #ifdef CONFIG_NET_SWITCHDEV + u8 stp_state; /* STP state of this physical port */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)) + unsigned long brport_flags; /* bridge port flags */ ++#else ++ struct switchdev_brport_flags brport_flags; /* bridge port flags */ ++#endif + #endif + uint32_t rx_page_mode; /* page mode for Rx processing */ + uint32_t rx_jumbo_mru; /* Jumbo mru value for Rx processing */ +--- a/nss_dp_switchdev.c ++++ b/nss_dp_switchdev.c +@@ -296,7 +296,11 @@ static int nss_dp_port_attr_set(struct n + switch (attr->id) { + case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS: + dp_priv->brport_flags = attr->u.brport_flags; ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)) + netdev_dbg(dev, "set brport_flags %lu\n", attr->u.brport_flags); ++#else ++ netdev_dbg(dev, "set brport_flags %lu\n", attr->u.brport_flags.val); ++#endif + return 0; + case SWITCHDEV_ATTR_ID_PORT_STP_STATE: + return nss_dp_stp_state_set(dp_priv, attr->u.stp_state); diff --git a/package/qca/nss/qca-nss-dp/patches/0010-switchdev-fix-FDB-roaming.patch b/package/qca/nss/qca-nss-dp/patches/0010-switchdev-fix-FDB-roaming.patch new file mode 100644 index 000000000..19395ac42 --- /dev/null +++ b/package/qca/nss/qca-nss-dp/patches/0010-switchdev-fix-FDB-roaming.patch @@ -0,0 +1,110 @@ +From d16102cad769f430144ca8094d928762b445e9b0 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 18 Mar 2022 22:02:01 +0100 +Subject: [PATCH] switchdev: fix FDB roaming + +Try and solve the roaming issue by trying to replicate what NSS bridge +module is doing, but by utilizing switchdev FDB notifiers instead of +adding new notifiers to the bridge code. + +We register a new non-blocking switchdev notifier and simply wait for +notification, and then process the SWITCHDEV_FDB_DEL_TO_DEVICE +notifications. + +Those tell us that a certain FDB entry should be removed, then a VSI ID +is fetched for the physical PPE port and using that VSI ID and the +notification provided MAC adress existing FDB entry gets removed. + +Signed-off-by: Robert Marko +--- + nss_dp_switchdev.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 61 insertions(+) + +--- a/nss_dp_switchdev.c ++++ b/nss_dp_switchdev.c +@@ -24,6 +24,8 @@ + #include "nss_dp_dev.h" + #include "fal/fal_stp.h" + #include "fal/fal_ctrlpkt.h" ++#include "fal/fal_fdb.h" ++#include "ref/ref_vsi.h" + + #define NSS_DP_SWITCH_ID 0 + #define NSS_DP_SW_ETHTYPE_PID 0 /* PPE ethtype profile ID for slow protocols */ +@@ -348,10 +350,64 @@ static int nss_dp_switchdev_event(struct + return NOTIFY_DONE; + } + ++static int nss_dp_switchdev_fdb_del_event(struct net_device *netdev, ++ struct switchdev_notifier_fdb_info *fdb_info) ++{ ++ struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); ++ fal_fdb_entry_t entry; ++ a_uint32_t vsi_id; ++ sw_error_t rv; ++ ++ netdev_dbg(netdev, "FDB DEL %pM port %d\n", fdb_info->addr, dp_priv->macid); ++ ++ rv = ppe_port_vsi_get(NSS_DP_SWITCH_ID, dp_priv->macid, &vsi_id); ++ if (rv) { ++ netdev_err(netdev, "cannot get VSI ID for port %d\n", dp_priv->macid); ++ return notifier_from_errno(rv); ++ } ++ ++ memset(&entry, 0, sizeof(entry)); ++ memcpy(&entry.addr, fdb_info->addr, ETH_ALEN); ++ entry.fid = vsi_id; ++ ++ rv = fal_fdb_entry_del_bymac(NSS_DP_SWITCH_ID, &entry); ++ if (rv) { ++ netdev_err(netdev, "FDB entry delete failed with MAC %pM and fid %d\n", ++ &entry.addr, entry.fid); ++ return notifier_from_errno(rv); ++ } ++ ++ return notifier_from_errno(rv); ++} ++ ++static int nss_dp_fdb_switchdev_event(struct notifier_block *nb, ++ unsigned long event, void *ptr) ++{ ++ struct net_device *dev = switchdev_notifier_info_to_dev(ptr); ++ ++ /* ++ * Handle switchdev event only for physical devices ++ */ ++ if (!nss_dp_is_phy_dev(dev)) { ++ return NOTIFY_DONE; ++ } ++ ++ switch (event) { ++ case SWITCHDEV_FDB_DEL_TO_DEVICE: ++ return nss_dp_switchdev_fdb_del_event(dev, ptr); ++ } ++ ++ return NOTIFY_DONE; ++} ++ + static struct notifier_block nss_dp_switchdev_notifier = { + .notifier_call = nss_dp_switchdev_event, + }; + ++static struct notifier_block nss_dp_switchdev_fdb_notifier = { ++ .notifier_call = nss_dp_fdb_switchdev_event, ++}; ++ + static bool switch_init_done; + + /* +@@ -366,6 +422,11 @@ void nss_dp_switchdev_setup(struct net_d + return; + } + ++ err = register_switchdev_notifier(&nss_dp_switchdev_fdb_notifier); ++ if (err) { ++ netdev_dbg(dev, "%px:Failed to register switchdev FDB notifier\n", dev); ++ } ++ + err = register_switchdev_blocking_notifier(&nss_dp_switchdev_notifier); + if (err) { + netdev_dbg(dev, "%px:Failed to register switchdev notifier\n", dev); diff --git a/package/qca/nss/qca-nss-dp/patches/0011-treewide-fix-confusing-printing-of-registered-netdev.patch b/package/qca/nss/qca-nss-dp/patches/0011-treewide-fix-confusing-printing-of-registered-netdev.patch new file mode 100644 index 000000000..6c3d68f77 --- /dev/null +++ b/package/qca/nss/qca-nss-dp/patches/0011-treewide-fix-confusing-printing-of-registered-netdev.patch @@ -0,0 +1,31 @@ +From 7e4ae2d6285095794d73d2f2ce61404f61d4e633 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Tue, 17 May 2022 15:55:36 +0200 +Subject: [PATCH 11/11] treewide: fix confusing printing of registered netdev + +Net core implementation changed and now printing the netdev name cause +confusing printing if done before register_netdev. Move the old printing +to dbg and add an additional info log right after register_netdev to +give the user some info on correct nss-dp probe. + +Signed-off-by: Ansuel Smith +--- + nss_dp_main.c | 3 +++ + 1 files changed, 3 insertions(+), 0 deletions(-) + +diff --git a/nss_dp_main.c b/nss_dp_main.c +index c0ae9d6..441c300 100644 +--- a/nss_dp_main.c ++++ b/nss_dp_main.c +@@ -875,6 +875,9 @@ static int32_t nss_dp_probe(struct platform_device *pdev) + goto phy_setup_fail; + } + ++ netdev_info(netdev, "Registered netdev %s(qcom-id:%d)\n", ++ netdev->name, port_id); ++ + dp_global_ctx.nss_dp[dp_priv->macid - 1] = dp_priv; + dp_global_ctx.slowproto_acl_bm = 0; + +-- +2.34.1 diff --git a/package/qca/nss/qca-nss-drv-64/patches/0005-nss-drv-add-support-for-kernel-5.15.patch b/package/qca/nss/qca-nss-drv-64/patches/0005-nss-drv-add-support-for-kernel-5.15.patch new file mode 100644 index 000000000..dfebd0d6f --- /dev/null +++ b/package/qca/nss/qca-nss-drv-64/patches/0005-nss-drv-add-support-for-kernel-5.15.patch @@ -0,0 +1,73 @@ +From 6e65f6daecb09463688eaea0a234018a728196b8 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Tue, 5 Apr 2022 18:10:57 +0200 +Subject: [PATCH 5/8] nss-drv: add support for kernel 5.15 + +- Fix coredump panic notifier include change. +- Fix skb ZEROCOPY flag. +- Add skb reuse support for 5.15 kernel version. + +Signed-off-by: Ansuel Smith +--- + nss_core.c | 5 +++-- + nss_coredump.c | 4 ++++ + nss_hal/nss_hal.c | 1 + + 3 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/nss_core.c b/nss_core.c +index f9e6014..8cd1d4b 100644 +--- a/nss_core.c ++++ b/nss_core.c +@@ -53,7 +53,8 @@ + (((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)))) || \ + (((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)))) || \ + (((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)))) || \ +-(((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)))))) ++(((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)))) || \ ++(((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)))))) + #error "Check skb recycle code in this file to match Linux version" + #endif + +@@ -2623,7 +2624,11 @@ static inline bool nss_core_skb_can_reuse(struct nss_ctx_instance *nss_ctx, + if (unlikely(irqs_disabled())) + return false; + ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0)) + if (unlikely(skb_shinfo(nbuf)->tx_flags & SKBTX_DEV_ZEROCOPY)) ++#else ++ if (unlikely(skb_shinfo(nbuf)->flags & SKBFL_ZEROCOPY_ENABLE)) ++#endif + return false; + + if (unlikely(skb_is_nonlinear(nbuf))) +diff --git a/nss_coredump.c b/nss_coredump.c +index ecad659..3ecef7e 100644 +--- a/nss_coredump.c ++++ b/nss_coredump.c +@@ -23,7 +23,11 @@ + #include "nss_hal.h" + #include "nss_log.h" + #include ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0)) + #include /* for panic_notifier_list */ ++#else ++#include ++#endif + #include /* for time */ + #include "nss_tx_rx_common.h" + +diff --git a/nss_hal/nss_hal.c b/nss_hal/nss_hal.c +index 57974c1..d8c703b 100644 +--- a/nss_hal/nss_hal.c ++++ b/nss_hal/nss_hal.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #include "nss_hal.h" + #include "nss_arch.h" +-- +2.34.1 + diff --git a/package/qca/nss/qca-nss-drv-64/patches/0005-nss-drv-use-standard-skb_skip_tc_classify-instead-of.patch b/package/qca/nss/qca-nss-drv-64/patches/0005-nss-drv-use-standard-skb_skip_tc_classify-instead-of.patch new file mode 100644 index 000000000..73c923d3d --- /dev/null +++ b/package/qca/nss/qca-nss-drv-64/patches/0005-nss-drv-use-standard-skb_skip_tc_classify-instead-of.patch @@ -0,0 +1,29 @@ +From 4dd701916186803172a9f35e7e982a953613ad55 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Mon, 11 Apr 2022 21:32:41 +0200 +Subject: [PATCH 5/9] nss-drv: use standard skb_skip_tc_classify instead of + custom api + +Use skb_skip_tc_classify to skip classify for packet handled by nss +instead of custom api. + +Signed-off-by: Ansuel Smith +--- + nss_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/nss_core.c b/nss_core.c +index f9e6014..6ab8038 100644 +--- a/nss_core.c ++++ b/nss_core.c +@@ -1075,7 +1075,7 @@ static inline void nss_core_set_skb_classify(struct sk_buff *nbuf) + #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)) + nbuf->tc_verd = SET_TC_NCLS_NSS(nbuf->tc_verd); + #else +- skb_set_tc_classify_offload(nbuf); ++ skb_skip_tc_classify(nbuf); + #endif + #endif + } +-- +2.34.1 diff --git a/package/qca/nss/qca-nss-drv-64/patches/999-treewide-hack-support-for-mismatched-firmware.patch b/package/qca/nss/qca-nss-drv-64/patches/0999-treewide-hack-support-for-mismatched-firmware.patch similarity index 100% rename from package/qca/nss/qca-nss-drv-64/patches/999-treewide-hack-support-for-mismatched-firmware.patch rename to package/qca/nss/qca-nss-drv-64/patches/0999-treewide-hack-support-for-mismatched-firmware.patch diff --git a/package/qca/nss/qca-nss-ecm-64/Makefile b/package/qca/nss/qca-nss-ecm-64/Makefile index 77afbb204..a22d32851 100644 --- a/package/qca/nss/qca-nss-ecm-64/Makefile +++ b/package/qca/nss/qca-nss-ecm-64/Makefile @@ -19,7 +19,7 @@ define KernelPackage/qca-nss-ecm-64 CATEGORY:=Kernel modules SUBMENU:=Network Support DEPENDS:=@(TARGET_ipq807x||TARGET_ipq60xx) \ - +kmod-qca-nss-drv-64 \ + +kmod-qca-nss-drv-64 \ +iptables-mod-extra \ +kmod-ipt-conntrack \ +kmod-ipt-physdev \ diff --git a/package/qca/nss/qca-nss-ecm-64/files/ecm_dump.sh b/package/qca/nss/qca-nss-ecm-64/files/ecm_dump.sh old mode 100755 new mode 100644 diff --git a/package/qca/nss/qca-nss-ecm-64/patches/100-kernel-5.10-support.patch b/package/qca/nss/qca-nss-ecm-64/patches/002-kernel-5.10-support.patch similarity index 100% rename from package/qca/nss/qca-nss-ecm-64/patches/100-kernel-5.10-support.patch rename to package/qca/nss/qca-nss-ecm-64/patches/002-kernel-5.10-support.patch diff --git a/package/qca/nss/qca-nss-ecm-64/patches/203-rework-nfct-notification.patch b/package/qca/nss/qca-nss-ecm-64/patches/003-rework-nfct-notification.patch similarity index 100% rename from package/qca/nss/qca-nss-ecm-64/patches/203-rework-nfct-notification.patch rename to package/qca/nss/qca-nss-ecm-64/patches/003-rework-nfct-notification.patch diff --git a/package/qca/nss/qca-nss-ecm-64/patches/204-More-compile-fixes.patch b/package/qca/nss/qca-nss-ecm-64/patches/004-More-compile-fixes.patch similarity index 100% rename from package/qca/nss/qca-nss-ecm-64/patches/204-More-compile-fixes.patch rename to package/qca/nss/qca-nss-ecm-64/patches/004-More-compile-fixes.patch diff --git a/package/qca/nss/qca-nss-ecm-64/patches/205-resolve-high-load.patch b/package/qca/nss/qca-nss-ecm-64/patches/005-resolve-high-load.patch similarity index 100% rename from package/qca/nss/qca-nss-ecm-64/patches/205-resolve-high-load.patch rename to package/qca/nss/qca-nss-ecm-64/patches/005-resolve-high-load.patch diff --git a/package/qca/nss/qca-nss-ecm-64/patches/006-ecm_interface-switch-to-kernel_recvmsg-api.patch b/package/qca/nss/qca-nss-ecm-64/patches/006-ecm_interface-switch-to-kernel_recvmsg-api.patch new file mode 100644 index 000000000..caa591abf --- /dev/null +++ b/package/qca/nss/qca-nss-ecm-64/patches/006-ecm_interface-switch-to-kernel_recvmsg-api.patch @@ -0,0 +1,40 @@ +diff --git a/ecm_interface.c b/ecm_interface.c +index b461456..6be872a 100644 +--- a/ecm_interface.c ++++ b/ecm_interface.c +@@ -7493,9 +7493,13 @@ + static int ecm_interface_wifi_event_rx(struct socket *sock, struct sockaddr_nl *addr, unsigned char *buf, int len) + { + struct msghdr msg; ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) + struct iovec iov; + mm_segment_t oldfs; + int size; ++#else ++ struct kvec iov; ++#endif + + iov.iov_base = buf; + iov.iov_len = len; +@@ -7505,9 +7509,10 @@ + msg.msg_namelen = sizeof(struct sockaddr_nl); + msg.msg_control = NULL; + msg.msg_controllen = 0; +- iov_iter_init(&msg.msg_iter, READ, &iov, 1, 1); ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) + oldfs = get_fs(); + set_fs(KERNEL_DS); ++ iov_iter_init(&msg.msg_iter, READ, &iov, 1, 1); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0)) + size = sock_recvmsg(sock, &msg, len, msg.msg_flags); + #else +@@ -7516,6 +7521,9 @@ + set_fs(oldfs); + + return size; ++#else ++ return kernel_recvmsg(sock, &msg, &iov, 1, iov.iov_len, 0); ++#endif + } + + /* diff --git a/package/qca/nss/qca-nss-ecm-64/patches/007-treewide-rework-notifier-changes-for-5.15.patch b/package/qca/nss/qca-nss-ecm-64/patches/007-treewide-rework-notifier-changes-for-5.15.patch new file mode 100644 index 000000000..262a8fb85 --- /dev/null +++ b/package/qca/nss/qca-nss-ecm-64/patches/007-treewide-rework-notifier-changes-for-5.15.patch @@ -0,0 +1,72 @@ +From e9073363a50a25bddd96e808f04bcf56c45da4ac Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sun, 8 May 2022 18:19:47 +0200 +Subject: [PATCH 07/12] treewide: rework notifier changes for 5.15 + +Rework notifier changes for 5.15 conntrack new implementation. + +Signed-off-by: Ansuel Smith +--- + ecm_conntrack_notifier.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/ecm_conntrack_notifier.c b/ecm_conntrack_notifier.c +index 9c8a45e..9f2cdae 100644 +--- a/ecm_conntrack_notifier.c ++++ b/ecm_conntrack_notifier.c +@@ -322,7 +322,7 @@ EXPORT_SYMBOL(ecm_conntrack_ipv4_event); + #ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + static int ecm_conntrack_event(struct notifier_block *this, unsigned long events, void *ptr) + #else +-static int ecm_conntrack_event(unsigned int events, struct nf_ct_event *item) ++static int ecm_conntrack_event(unsigned int events, const struct nf_ct_event *item) + #endif + { + #ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS +@@ -388,7 +388,11 @@ static struct notifier_block ecm_conntrack_notifier = { + * Netfilter conntrack event system to monitor connection tracking changes + */ + static struct nf_ct_event_notifier ecm_conntrack_notifier = { ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) + .fcn = ecm_conntrack_event, ++#else ++ .ct_event = ecm_conntrack_event, ++#endif + }; + #endif + #endif +@@ -426,13 +430,19 @@ int ecm_conntrack_notifier_init(struct dentry *dentry) + #ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + result = nf_conntrack_register_chain_notifier(&init_net, &ecm_conntrack_notifier); + #else ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) + result = nf_conntrack_register_notifier(&init_net, &ecm_conntrack_notifier); ++#else ++ nf_conntrack_register_notifier(&init_net, &ecm_conntrack_notifier); ++#endif + #endif ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) + if (result < 0) { + DEBUG_ERROR("Can't register nf notifier hook.\n"); + debugfs_remove_recursive(ecm_conntrack_notifier_dentry); + return result; + } ++#endif + #endif + + return 0; +@@ -448,7 +458,11 @@ void ecm_conntrack_notifier_exit(void) + #ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + nf_conntrack_unregister_chain_notifier(&init_net, &ecm_conntrack_notifier); + #else ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) + nf_conntrack_unregister_notifier(&init_net, &ecm_conntrack_notifier); ++#else ++ nf_conntrack_unregister_notifier(&init_net); ++#endif + #endif + /* + * Remove the debugfs files recursively. +-- +2.34.1 + diff --git a/package/qca/nss/qca-nss-ecm-64/patches/008-frontends-drop-use-of-static-be_liberal-and-no_windo.patch b/package/qca/nss/qca-nss-ecm-64/patches/008-frontends-drop-use-of-static-be_liberal-and-no_windo.patch new file mode 100644 index 000000000..c5989cc1b --- /dev/null +++ b/package/qca/nss/qca-nss-ecm-64/patches/008-frontends-drop-use-of-static-be_liberal-and-no_windo.patch @@ -0,0 +1,156 @@ +--- a/frontends/nss/ecm_nss_ported_ipv4.c ++++ b/frontends/nss/ecm_nss_ported_ipv4.c +@@ -125,6 +125,7 @@ + static int ecm_nss_ported_ipv4_accelerated_count[ECM_NSS_PORTED_IPV4_PROTO_MAX] = {0}; + /* Array of Number of TCP and UDP connections currently offloaded */ + ++ #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) + /* + * Expose what should be a static flag in the TCP connection tracker. + */ +@@ -132,6 +133,7 @@ + extern int nf_ct_tcp_no_window_check; + #endif + extern int nf_ct_tcp_be_liberal; ++#endif + + /* + * ecm_nss_ported_ipv4_connection_callback() +@@ -372,6 +374,10 @@ + uint8_t dest_mac_xlate[ETH_ALEN]; + ecm_db_direction_t ecm_dir; + ecm_front_end_acceleration_mode_t result_mode; ++#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 12, 0) ++ struct net *net = nf_ct_net(ct); ++ struct nf_tcp_net *tn = nf_tcp_pernet(net); ++#endif + + DEBUG_CHECK_MAGIC(npci, ECM_NSS_PORTED_IPV4_CONNECTION_INSTANCE_MAGIC, "%px: magic failed", npci); + +@@ -1236,9 +1242,17 @@ + nircm->tcp_rule.return_end = ct->proto.tcp.seen[return_dir].td_end; + nircm->tcp_rule.return_max_end = ct->proto.tcp.seen[return_dir].td_maxend; + #ifdef ECM_OPENWRT_SUPPORT ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) + if (nf_ct_tcp_be_liberal || nf_ct_tcp_no_window_check + #else ++ if (tn->tcp_be_liberal || tn->tcp_no_window_check ++#endif ++#else ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) + if (nf_ct_tcp_be_liberal ++#else ++ if (tn->tcp_be_liberal ++#endif + #endif + || (ct->proto.tcp.seen[flow_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL) + || (ct->proto.tcp.seen[return_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL)) { +--- a/frontends/nss/ecm_nss_ported_ipv6.c ++++ b/frontends/nss/ecm_nss_ported_ipv6.c +@@ -125,6 +125,7 @@ + static int ecm_nss_ported_ipv6_accelerated_count[ECM_NSS_PORTED_IPV6_PROTO_MAX] = {0}; + /* Array of Number of TCP and UDP connections currently offloaded */ + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) + /* + * Expose what should be a static flag in the TCP connection tracker. + */ +@@ -132,6 +133,7 @@ + extern int nf_ct_tcp_no_window_check; + #endif + extern int nf_ct_tcp_be_liberal; ++#endif + + /* + * ecm_nss_ported_ipv6_connection_callback() +@@ -376,6 +378,10 @@ + ip_addr_t src_ip; + ip_addr_t dest_ip; + ecm_front_end_acceleration_mode_t result_mode; ++#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 12, 0) ++ struct net *net = nf_ct_net(ct); ++ struct nf_tcp_net *tn = nf_tcp_pernet(net); ++#endif + + DEBUG_CHECK_MAGIC(npci, ECM_NSS_PORTED_IPV6_CONNECTION_INSTANCE_MAGIC, "%px: magic failed", npci); + +@@ -1162,9 +1168,17 @@ + nircm->tcp_rule.return_end = ct->proto.tcp.seen[return_dir].td_end; + nircm->tcp_rule.return_max_end = ct->proto.tcp.seen[return_dir].td_maxend; + #ifdef ECM_OPENWRT_SUPPORT ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) + if (nf_ct_tcp_be_liberal || nf_ct_tcp_no_window_check + #else ++ if (tn->tcp_be_liberal || tn->tcp_no_window_check ++#endif ++#else ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) + if (nf_ct_tcp_be_liberal ++#else ++ if (tn->tcp_be_liberal ++#endif + #endif + || (ct->proto.tcp.seen[flow_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL) + || (ct->proto.tcp.seen[return_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL)) { +--- a/frontends/sfe/ecm_sfe_ported_ipv4.c ++++ b/frontends/sfe/ecm_sfe_ported_ipv4.c +@@ -422,6 +422,10 @@ + int32_t interface_type_counts[ECM_DB_IFACE_TYPE_COUNT]; + bool rule_invalid; + ecm_db_direction_t ecm_dir; ++#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 12, 0) ++ struct net *net = nf_ct_net(ct); ++ struct nf_tcp_net *tn = nf_tcp_pernet(net); ++#endif + ecm_front_end_acceleration_mode_t result_mode; + + DEBUG_CHECK_MAGIC(npci, ECM_SFE_PORTED_IPV4_CONNECTION_INSTANCE_MAGIC, "%px: magic failed", npci); +@@ -1333,9 +1337,17 @@ + nircm->tcp_rule.return_end = ct->proto.tcp.seen[return_dir].td_end; + nircm->tcp_rule.return_max_end = ct->proto.tcp.seen[return_dir].td_maxend; + #ifdef ECM_OPENWRT_SUPPORT ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) + if (nf_ct_tcp_be_liberal || nf_ct_tcp_no_window_check + #else ++ if (tn->tcp_be_liberal || tn->tcp_no_window_check) ++#endif ++#else ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) + if (nf_ct_tcp_be_liberal ++#else ++ if (tn->tcp_be_liberal) ++#endif + #endif + || (ct->proto.tcp.seen[flow_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL) + || (ct->proto.tcp.seen[return_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL)) { +--- a/frontends/sfe/ecm_sfe_ported_ipv6.c ++++ b/frontends/sfe/ecm_sfe_ported_ipv6.c +@@ -426,6 +426,10 @@ + int32_t interface_type_counts[ECM_DB_IFACE_TYPE_COUNT]; + bool rule_invalid; + ip_addr_t src_ip; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) ++ struct net *net = nf_ct_net(ct); ++ struct nf_tcp_net *tn = nf_tcp_pernet(net); ++#endif + ip_addr_t dest_ip; + ecm_front_end_acceleration_mode_t result_mode; + +@@ -1293,9 +1297,17 @@ + nircm->tcp_rule.return_end = ct->proto.tcp.seen[return_dir].td_end; + nircm->tcp_rule.return_max_end = ct->proto.tcp.seen[return_dir].td_maxend; + #ifdef ECM_OPENWRT_SUPPORT ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) + if (nf_ct_tcp_be_liberal || nf_ct_tcp_no_window_check + #else ++ if (tn->tcp_be_liberal || tn->tcp_no_window_check) ++#endif ++#else ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) + if (nf_ct_tcp_be_liberal ++#else ++ if (tn->tcp_be_liberal) ++#endif + #endif + || (ct->proto.tcp.seen[flow_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL) + || (ct->proto.tcp.seen[return_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL)) { diff --git a/package/qca/nss/qca-nss-ecm-64/patches/009-ecm_tracker_datagram-drop-static-for-EXPORT_SYMBOL.patch b/package/qca/nss/qca-nss-ecm-64/patches/009-ecm_tracker_datagram-drop-static-for-EXPORT_SYMBOL.patch new file mode 100644 index 000000000..1bcaa12ef --- /dev/null +++ b/package/qca/nss/qca-nss-ecm-64/patches/009-ecm_tracker_datagram-drop-static-for-EXPORT_SYMBOL.patch @@ -0,0 +1,55 @@ +From 9827d8597545ecfee17eba7b08d48dbcdf55c614 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sun, 8 May 2022 18:39:39 +0200 +Subject: [PATCH 09/12] ecm_tracker_datagram: drop static for EXPORT_SYMBOL + +EXPORT_SYMBOL should NOT be static + +Signed-off-by: Ansuel Smith +--- + ecm_tracker_datagram.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/ecm_tracker_datagram.c b/ecm_tracker_datagram.c +index 9c04d73..ae14146 100644 +--- a/ecm_tracker_datagram.c ++++ b/ecm_tracker_datagram.c +@@ -203,7 +203,7 @@ static void ecm_tracker_datagram_datagram_discard(struct ecm_tracker_datagram_in + * ecm_tracker_datagram_discard_all() + * Discard all tracked data + */ +-static void ecm_tracker_datagram_discard_all(struct ecm_tracker_datagram_internal_instance *dtii) ++void ecm_tracker_datagram_discard_all(struct ecm_tracker_datagram_internal_instance *dtii) + { + int32_t src_count; + int32_t dest_count; +@@ -364,7 +364,7 @@ static void ecm_tracker_datagram_datagram_discard_callback(struct ecm_tracker_in + * ecm_tracker_datagram_datagram_size_get() + * Return size in bytes of datagram at index i that was sent to the target + */ +-static int32_t ecm_tracker_datagram_datagram_size_get(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, int32_t i) ++int32_t ecm_tracker_datagram_datagram_size_get(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, int32_t i) + { + struct ecm_tracker_datagram_internal_instance *dtii = (struct ecm_tracker_datagram_internal_instance *)uti; + +@@ -412,7 +412,7 @@ static int32_t ecm_tracker_datagram_datagram_size_get_callback(struct ecm_tracke + * ecm_tracker_datagram_datagram_read() + * Read size bytes from datagram at index i into the buffer + */ +-static int ecm_tracker_datagram_datagram_read(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, int32_t i, int32_t offset, int32_t size, void *buffer) ++int ecm_tracker_datagram_datagram_read(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, int32_t i, int32_t offset, int32_t size, void *buffer) + { + struct ecm_tracker_datagram_internal_instance *dtii = (struct ecm_tracker_datagram_internal_instance *)uti; + int res; +@@ -466,7 +466,7 @@ static int ecm_tracker_datagram_datagram_read_callback(struct ecm_tracker_instan + * ecm_tracker_datagram_datagram_add() + * Append the datagram onto the tracker queue for the given target + */ +-static bool ecm_tracker_datagram_datagram_add(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, struct sk_buff *skb) ++bool ecm_tracker_datagram_datagram_add(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, struct sk_buff *skb) + { + struct ecm_tracker_datagram_internal_instance *dtii = (struct ecm_tracker_datagram_internal_instance *)uti; + struct sk_buff *skbc; +-- +2.34.1 + diff --git a/package/qca/nss/qca-nss-ecm-64/patches/010-frontends-drop-udp_get_timeouts-and-use-standard-ups.patch b/package/qca/nss/qca-nss-ecm-64/patches/010-frontends-drop-udp_get_timeouts-and-use-standard-ups.patch new file mode 100644 index 000000000..da88eea4c --- /dev/null +++ b/package/qca/nss/qca-nss-ecm-64/patches/010-frontends-drop-udp_get_timeouts-and-use-standard-ups.patch @@ -0,0 +1,74 @@ +From ef638a84405c9f6556a9d7c257ccbba74efd228e Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sat, 14 May 2022 20:15:10 +0200 +Subject: [PATCH 10/12] frontends: drop udp_get_timeouts and use standard + upstream api + +Drop udp_get_timeouts and use nf_udp_pernet and ->timeoutrs +instead or relying on a downstream api not present upstream. +--- + frontends/nss/ecm_nss_ipv4.c | 3 ++- + frontends/nss/ecm_nss_ipv6.c | 3 ++- + frontends/sfe/ecm_sfe_ipv4.c | 3 ++- + frontends/sfe/ecm_sfe_ipv6.c | 3 ++- + 4 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/frontends/nss/ecm_nss_ipv4.c b/frontends/nss/ecm_nss_ipv4.c +index 719a747..558819a 100644 +--- a/frontends/nss/ecm_nss_ipv4.c ++++ b/frontends/nss/ecm_nss_ipv4.c +@@ -607,7 +607,8 @@ sync_conntrack: + #else + timeouts = nf_ct_timeout_lookup(ct); + if (!timeouts) { +- timeouts = udp_get_timeouts(nf_ct_net(ct)); ++ struct nf_udp_net *un = nf_udp_pernet(nf_ct_net(ct)); ++ timeouts = un->timeouts; + } + + spin_lock_bh(&ct->lock); +diff --git a/frontends/nss/ecm_nss_ipv6.c b/frontends/nss/ecm_nss_ipv6.c +index 67ee364..51eb069 100644 +--- a/frontends/nss/ecm_nss_ipv6.c ++++ b/frontends/nss/ecm_nss_ipv6.c +@@ -586,7 +586,8 @@ sync_conntrack: + #else + timeouts = nf_ct_timeout_lookup(ct); + if (!timeouts) { +- timeouts = udp_get_timeouts(nf_ct_net(ct)); ++ struct nf_udp_net *un = nf_udp_pernet(nf_ct_net(ct)); ++ timeouts = un->timeouts; + } + + spin_lock_bh(&ct->lock); +diff --git a/frontends/sfe/ecm_sfe_ipv4.c b/frontends/sfe/ecm_sfe_ipv4.c +index 3f30821..931af5d 100644 +--- a/frontends/sfe/ecm_sfe_ipv4.c ++++ b/frontends/sfe/ecm_sfe_ipv4.c +@@ -527,7 +527,8 @@ sync_conntrack: + #else + timeouts = nf_ct_timeout_lookup(ct); + if (!timeouts) { +- timeouts = udp_get_timeouts(nf_ct_net(ct)); ++ struct nf_udp_net *un = nf_udp_pernet(nf_ct_net(ct)); ++ timeouts = un->timeouts; + } + + spin_lock_bh(&ct->lock); +diff --git a/frontends/sfe/ecm_sfe_ipv6.c b/frontends/sfe/ecm_sfe_ipv6.c +index 54fdbf3..63d8888 100644 +--- a/frontends/sfe/ecm_sfe_ipv6.c ++++ b/frontends/sfe/ecm_sfe_ipv6.c +@@ -516,7 +516,8 @@ sync_conntrack: + #else + timeouts = nf_ct_timeout_lookup(ct); + if (!timeouts) { +- timeouts = udp_get_timeouts(nf_ct_net(ct)); ++ struct nf_udp_net *un = nf_udp_pernet(nf_ct_net(ct)); ++ timeouts = un->timeouts; + } + + spin_lock_bh(&ct->lock); +-- +2.34.1 + diff --git a/package/qca/nss/qca-nss-ecm-64/patches/901-qca-nss-ecm-fix-a-memcpy-overflow-in-ecm_db.patch b/package/qca/nss/qca-nss-ecm-64/patches/901-qca-nss-ecm-fix-a-memcpy-overflow-in-ecm_db.patch new file mode 100644 index 000000000..491cbedcc --- /dev/null +++ b/package/qca/nss/qca-nss-ecm-64/patches/901-qca-nss-ecm-fix-a-memcpy-overflow-in-ecm_db.patch @@ -0,0 +1,67 @@ +From 1958e34c4c1b8b4fb62eba693fbd7693536947b9 Mon Sep 17 00:00:00 2001 +From: flebourse +Date: Thu, 23 Dec 2021 16:11:06 +0100 +Subject: [PATCH] qca-nss-ecm: fix a memcpy overflow in ecm_db + +Calls to ipv6_addr_prefix() trigger a memcpy overflow if the prefix len +argument is greater than 128, cap it at this value. + +stack bactrace: +detected buffer overflow in memcpy +Kernel BUG at fortify_panic+0x20/0x24 +Internal error: Oops - BUG: 0 [#1] SMP +CPU: 2 PID: 2592 Comm: netifd Not tainted 5.10.80 #0 +Hardware name: Xiaomi AX9000 (DT) +Call trace: + fortify_panic+0x20/0x24 + ecm_db_exit+0x42c/0x49c [ecm] + ecm_db_exit+0x464/0x49c [ecm] + atomic_notifier_call_chain+0x5c/0x90 + ip6_route_add+0x13c/0x1a4 + inet6_rtm_newroute+0x98/0xa0 + rtnetlink_rcv_msg+0x10c/0x34c + netlink_rcv_skb+0x5c/0x130 + rtnetlink_rcv+0x1c/0x2c + netlink_unicast+0x1ec/0x2e0 + netlink_sendmsg+0x1a4/0x394 + ____sys_sendmsg+0x270/0x2b4 + ___sys_sendmsg+0x7c/0xc0 + __sys_sendmsg+0x5c/0xb0 + __arm64_sys_sendmsg+0x28/0x34 + el0_svc_common.constprop.0+0x88/0x190 + do_el0_svc+0x74/0x94 + el0_svc+0x14/0x20 + el0_sync_handler+0xa8/0x130 + el0_sync+0x184/0x1c0 +Code: aa0003e1 912b4040 910003fd 97fff56c (d4210000) + +Signed-off-By: Francis Le Bourse +--- + ecm_db/ecm_db.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/ecm_db/ecm_db.c b/ecm_db/ecm_db.c +index c6f408d..df04afd 100644 +--- a/ecm_db/ecm_db.c ++++ b/ecm_db/ecm_db.c +@@ -298,7 +298,7 @@ static int ecm_db_ipv6_route_table_update_event(struct notifier_block *nb, + * Compute ECM connection's prefix destination address by masking it with the + * route config's destination address prefix length. + */ +- ipv6_addr_prefix(&prefix_addr, &ecm_in6, cfg->fc_dst_len); ++ ipv6_addr_prefix(&prefix_addr, &ecm_in6, min(128, cfg->fc_dst_len)); + + DEBUG_TRACE("dest addr prefix: %pI6 prefix_len: %d ecm_in6: %pI6\n", &prefix_addr, cfg->fc_dst_len, &ecm_in6); + +@@ -326,7 +326,7 @@ static int ecm_db_ipv6_route_table_update_event(struct notifier_block *nb, + * Compute ECM connection's prefix source address by masking it with the + * route config's destination address prefix length. + */ +- ipv6_addr_prefix(&prefix_addr, &ecm_in6, cfg->fc_dst_len); ++ ipv6_addr_prefix(&prefix_addr, &ecm_in6, min(128, cfg->fc_dst_len)); + + DEBUG_TRACE("src addr prefix: %pI6 prefix_len: %d ecm_in6: %pI6\n", &prefix_addr, cfg->fc_dst_len, &ecm_in6); + +-- +2.1.4 + diff --git a/package/qca/nss/qca-nss-gmac/Makefile b/package/qca/nss/qca-nss-gmac/Makefile index 6e00c7a1a..8b39f0437 100644 --- a/package/qca/nss/qca-nss-gmac/Makefile +++ b/package/qca/nss/qca-nss-gmac/Makefile @@ -4,8 +4,8 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=qca-nss-gmac PKG_RELEASE:=1 -PKG_SOURCE_URL:=https://source.codeaurora.org/quic/qsdk/oss/lklm/nss-gmac PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://source.codeaurora.org/quic/qsdk/oss/lklm/nss-gmac PKG_SOURCE_VERSION:=9b74deef2816d91e58926e6fab7a6ff931eb3b22 PKG_MIRROR_HASH:=a1939caa638414323e60f7d29f797ea831c6036e424b8e7bd6cf2d3d874de064 @@ -15,7 +15,7 @@ define KernelPackage/qca-nss-gmac SECTION:=kernel CATEGORY:=Kernel modules SUBMENU:=Network Devices - DEPENDS:=@TARGET_ipq806x||TARGET_ipq_ipq806x @LINUX_5_4 + DEPENDS:=@TARGET_ipq806x @LINUX_5_4 TITLE:=Kernel driver for NSS gmac FILES:=$(PKG_BUILD_DIR)/ipq806x/qca-nss-gmac.ko AUTOLOAD:=$(call AutoLoad,31,qca-nss-gmac) diff --git a/package/qca/nss/qca-nss-gmac/patches/101-nss-gmac-test-ptr.patch b/package/qca/nss/qca-nss-gmac/patches/101-nss-gmac-test-ptr.patch index 0b1ff063d..a5bff16bd 100644 --- a/package/qca/nss/qca-nss-gmac/patches/101-nss-gmac-test-ptr.patch +++ b/package/qca/nss/qca-nss-gmac/patches/101-nss-gmac-test-ptr.patch @@ -1,11 +1,25 @@ --- a/ipq806x/nss_gmac_ctrl.c +++ b/ipq806x/nss_gmac_ctrl.c -@@ -992,7 +992,7 @@ static int32_t nss_gmac_of_get_pdata(str +@@ -957,7 +957,8 @@ static int32_t nss_gmac_of_get_pdata(struct device_node *np, + struct net_device *netdev, + struct msm_nss_gmac_platform_data *gmaccfg) + { +- uint8_t *maddr = NULL; ++ int ret; ++ u8 maddr[ETH_ALEN]; + struct nss_gmac_dev *gmacdev = (struct nss_gmac_dev *)netdev_priv(netdev); + struct resource memres_devtree = {0}; + +@@ -991,9 +992,9 @@ static int32_t nss_gmac_of_get_pdata(struct device_node *np, + pr_err("%s: Can't map interrupt\n", np->name); return -EFAULT; } - maddr = (uint8_t *)of_get_mac_address(np); +- maddr = (uint8_t *)of_get_mac_address(np); - if (maddr) -+ if (!IS_ERR_OR_NULL(maddr)) - memcpy(gmaccfg->mac_addr, maddr, ETH_ALEN); +- memcpy(gmaccfg->mac_addr, maddr, ETH_ALEN); ++ ret = of_get_mac_address(np, maddr); ++ if (!ret && is_valid_ether_addr(maddr)) ++ ether_addr_copy(gmaccfg->mac_addr, maddr); if (of_address_to_resource(np, 0, &memres_devtree) != 0) + return -EFAULT; diff --git a/package/qca/nss/qca-mcs/Makefile b/package/qca/qca-mcs/Makefile similarity index 65% rename from package/qca/nss/qca-mcs/Makefile rename to package/qca/qca-mcs/Makefile index 16129092e..af9372d89 100644 --- a/package/qca/nss/qca-mcs/Makefile +++ b/package/qca/qca-mcs/Makefile @@ -1,27 +1,28 @@ include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=qca-mcs PKG_RELEASE:=1 -PKG_SOURCE_URL:=https://source.codeaurora.org/quic/qsdk/oss/lklm/qca-mcs PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2021-10-28 +PKG_SOURCE_URL:=https://source.codeaurora.org/quic/qsdk/oss/lklm/qca-mcs PKG_SOURCE_VERSION:=31f5cd4b83da5a7c0fdca240b4e72677e4523b6e -PKG_MIRROR_HASH:=1b6997793b51cbeed9520d3183787aaf5ce283cf87ef6603c24cc342654dde61 +PKG_MIRROR_HASH:=3e2e25025dc2e771aafe7d8b12f26ac831d123b34bdd7b7e84bd39c1e933491d +include $(INCLUDE_DIR)/kernel.mk include $(INCLUDE_DIR)/package.mk define KernelPackage/qca-mcs SECTION:=kernel CATEGORY:=Kernel modules SUBMENU:=Network Support - URL:=http://www.qca.qualcomm.com - MAINTAINER:=Qualcomm Atheros, Inc. TITLE:=QCA Multicast Snooping Support - DEPENDS:= - KCONFIG:=CONFIG_NETFILTER=y CONFIG_BRIDGE_NETFILTER=y + DEPENDS:=@(TARGET_ipq806x||TARGET_ipq807x) + KCONFIG:= \ + CONFIG_NETFILTER=y \ + CONFIG_BRIDGE_NETFILTER=y FILES:=$(PKG_BUILD_DIR)/qca-mcs.ko - AUTOLOAD:=$(call AutoLoad,41,qca-mcs) + AUTOLOAD:=$(call AutoLoad,52,qca-mcs) endef define KernelPackage/qca-mcs/description @@ -39,17 +40,15 @@ define Build/InstallDev endef QCA_MC_SNOOPING_MAKE_OPTS:= \ - MC_SUPPORT_MLD=1 + $(KERNEL_MAKE_FLAGS) \ + CONFIG_SUPPORT_MLD=y \ + MDIR=$(PKG_BUILD_DIR) \ + KBUILDPATH=$(LINUX_DIR) \ + KERNELPATH=$(LINUX_SRC_DIR) \ + KERNELRELEASE=$(LINUX_RELEASE) define Build/Compile - $(MAKE) $(PKG_JOBS) -C $(LINUX_DIR) \ - $(KERNEL_MAKE_FLAGS) \ - KBUILDPATH=$(LINUX_DIR) \ - $(PKG_MAKE_FLAGS) \ - M=$(PKG_BUILD_DIR) \ - EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ - $(strip $(QCA_MC_SNOOPING_MAKE_OPTS)) \ - modules + $(MAKE) -C $(LINUX_DIR) M=$(PKG_BUILD_DIR) $(strip $(QCA_MC_SNOOPING_MAKE_OPTS)) endef $(eval $(call KernelPackage,qca-mcs)) diff --git a/package/qca/nss/qca-rfs/Makefile b/package/qca/qca-rfs/Makefile similarity index 100% rename from package/qca/nss/qca-rfs/Makefile rename to package/qca/qca-rfs/Makefile diff --git a/package/qca/nss/qca-rfs/files/qrfs.init b/package/qca/qca-rfs/files/qrfs.init similarity index 100% rename from package/qca/nss/qca-rfs/files/qrfs.init rename to package/qca/qca-rfs/files/qrfs.init diff --git a/package/qca/nss/qca-rfs/patches/100-add-kernel-5.4-support.patch b/package/qca/qca-rfs/patches/100-add-kernel-5.4-support.patch similarity index 100% rename from package/qca/nss/qca-rfs/patches/100-add-kernel-5.4-support.patch rename to package/qca/qca-rfs/patches/100-add-kernel-5.4-support.patch diff --git a/package/qca/nss/qca-rfs/patches/200-rework-nfct-notification.patch b/package/qca/qca-rfs/patches/200-rework-nfct-notification.patch similarity index 100% rename from package/qca/nss/qca-rfs/patches/200-rework-nfct-notification.patch rename to package/qca/qca-rfs/patches/200-rework-nfct-notification.patch diff --git a/package/qca/nss/qca-ssdk-shell/Makefile b/package/qca/qca-ssdk-shell/Makefile similarity index 100% rename from package/qca/nss/qca-ssdk-shell/Makefile rename to package/qca/qca-ssdk-shell/Makefile diff --git a/package/qca/nss/qca-ssdk/Makefile b/package/qca/qca-ssdk/Makefile similarity index 96% rename from package/qca/nss/qca-ssdk/Makefile rename to package/qca/qca-ssdk/Makefile index 3bb9d8ba9..487117bb6 100644 --- a/package/qca/nss/qca-ssdk/Makefile +++ b/package/qca/qca-ssdk/Makefile @@ -26,7 +26,7 @@ endef define KernelPackage/qca-ssdk-nohnat $(call KernelPackage/qca-ssdk/default-nohnat) - DEPENDS:=@(TARGET_ipq806x||TARGET_ipq807x) + DEPENDS:=@(TARGET_ipq806x||TARGET_ipq807x||TARGET_ipq60xx) VARIANT:=nohnat endef @@ -60,7 +60,7 @@ QCASSDK_CONFIG_OPTS+= \ TOOLPREFIX=$(TARGET_CROSS) \ TOOL_PATH=$(TOOLCHAIN_BIN_PATH) \ TARGET_SUFFIX=$(CONFIG_TARGET_SUFFIX) \ - EXTRA_CFLAGS=-I$(STAGING_DIR)/usr/include + EXTRA_CFLAGS=-fno-stack-protector -I$(STAGING_DIR)/usr/include ifeq ($(LOCAL_VARIANT),hnat) QCASSDK_CONFIG_OPTS+= HNAT_FEATURE=enable diff --git a/package/qca/nss/qca-ssdk/files/qca-ssdk b/package/qca/qca-ssdk/files/qca-ssdk similarity index 100% rename from package/qca/nss/qca-ssdk/files/qca-ssdk rename to package/qca/qca-ssdk/files/qca-ssdk diff --git a/package/qca/nss/qca-ssdk/patches/0001-SSDK-config-add-kernel-5.10.patch b/package/qca/qca-ssdk/patches/0001-SSDK-config-add-kernel-5.10-5.15.patch similarity index 83% rename from package/qca/nss/qca-ssdk/patches/0001-SSDK-config-add-kernel-5.10.patch rename to package/qca/qca-ssdk/patches/0001-SSDK-config-add-kernel-5.10-5.15.patch index 1ee44fa96..057652e45 100644 --- a/package/qca/nss/qca-ssdk/patches/0001-SSDK-config-add-kernel-5.10.patch +++ b/package/qca/qca-ssdk/patches/0001-SSDK-config-add-kernel-5.10-5.15.patch @@ -14,13 +14,17 @@ Signed-off-by: Robert Marko --- a/config +++ b/config -@@ -22,6 +22,10 @@ ifeq ($(KVER),$(filter 5.4%,$(KVER))) +@@ -22,6 +22,14 @@ ifeq ($(KVER),$(filter 5.4%,$(KVER))) OS_VER=5_4 endif +ifeq ($(KVER),$(filter 5.10%,$(KVER))) +OS_VER=5_10 +endif ++ ++ifeq ($(KVER),$(filter 5.15%,$(KVER))) ++OS_VER=5_15 ++endif + ifeq ($(KVER), 3.4.0) OS_VER=3_4 @@ -30,7 +34,7 @@ Signed-off-by: Robert Marko ifeq ($(ARCH), arm64) -ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4%,$(KVER))) -+ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4% 5.10%,$(KVER))) ++ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4% 5.10% 5.15%,$(KVER))) CPU_CFLAG= -DMODULE -Os -pipe -march=armv8-a -mcpu=cortex-a53+crypto -fno-caller-saves -fno-strict-aliasing -Werror -fno-common -Wno-format-security -Wno-pointer-sign -Wno-unused-but-set-variable -Wno-error=unused-result -mcmodel=large endif endif @@ -41,7 +45,7 @@ Signed-off-by: Robert Marko endif - ifeq (5_4, $(OS_VER)) -+ ifeq ($(OS_VER),$(filter 5_4 5_10, $(OS_VER))) ++ ifeq ($(OS_VER),$(filter 5_4 5_10 5_15, $(OS_VER))) ifeq ($(ARCH), arm64) KASAN_OPTION += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT) endif @@ -50,7 +54,7 @@ Signed-off-by: Robert Marko endif - ifeq ($(OS_VER),$(filter 4_4 5_4, $(OS_VER))) -+ ifeq ($(OS_VER),$(filter 4_4 5_4 5_10, $(OS_VER))) ++ ifeq ($(OS_VER),$(filter 4_4 5_4 5_10 5_15, $(OS_VER))) MODULE_CFLAG += -DKVER34 MODULE_CFLAG += -DKVER32 MODULE_CFLAG += -DLNX26_22 diff --git a/package/qca/nss/qca-ssdk/patches/0002-SSDK-replace-ioremap_nocache-with-ioremap.patch b/package/qca/qca-ssdk/patches/0002-SSDK-replace-ioremap_nocache-with-ioremap.patch similarity index 100% rename from package/qca/nss/qca-ssdk/patches/0002-SSDK-replace-ioremap_nocache-with-ioremap.patch rename to package/qca/qca-ssdk/patches/0002-SSDK-replace-ioremap_nocache-with-ioremap.patch diff --git a/package/qca/nss/qca-ssdk/patches/0004-platform-use-of_mdio_find_bus-to-get-MDIO-bus.patch b/package/qca/qca-ssdk/patches/0004-platform-use-of_mdio_find_bus-to-get-MDIO-bus.patch similarity index 100% rename from package/qca/nss/qca-ssdk/patches/0004-platform-use-of_mdio_find_bus-to-get-MDIO-bus.patch rename to package/qca/qca-ssdk/patches/0004-platform-use-of_mdio_find_bus-to-get-MDIO-bus.patch diff --git a/package/qca/nss/qca-ssdk/patches/0005-add-kernel-5.4-support.patch b/package/qca/qca-ssdk/patches/0005-add-kernel-5.4-support.patch similarity index 100% rename from package/qca/nss/qca-ssdk/patches/0005-add-kernel-5.4-support.patch rename to package/qca/qca-ssdk/patches/0005-add-kernel-5.4-support.patch diff --git a/package/qca/nss/qca-ssdk/patches/0006-fix-mdio-probe-on-ipq806x.patch b/package/qca/qca-ssdk/patches/0006-fix-mdio-probe-on-ipq806x.patch similarity index 100% rename from package/qca/nss/qca-ssdk/patches/0006-fix-mdio-probe-on-ipq806x.patch rename to package/qca/qca-ssdk/patches/0006-fix-mdio-probe-on-ipq806x.patch diff --git a/package/qca/qca-ssdk/patches/0007-SSDK-dts-fix-of_get_mac_address.patch b/package/qca/qca-ssdk/patches/0007-SSDK-dts-fix-of_get_mac_address.patch new file mode 100644 index 000000000..29be93128 --- /dev/null +++ b/package/qca/qca-ssdk/patches/0007-SSDK-dts-fix-of_get_mac_address.patch @@ -0,0 +1,42 @@ +From f3a7b93137c1a6a1b8010b86296242178eed5d9e Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 13 Aug 2021 20:03:21 +0200 +Subject: [PATCH] SSDK: dts: fix of_get_mac_address() + +Recently OpenWrt backported the updated of_get_mac_address() +function which returns and error code instead. + +So, patch the SSDK to use it and fix the compilation error. + +Signed-off-by: Robert Marko +--- + src/init/ssdk_dts.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/src/init/ssdk_dts.c ++++ b/src/init/ssdk_dts.c +@@ -779,8 +779,9 @@ static void ssdk_dt_parse_intf_mac(void) + { + struct device_node *dp_node = NULL; + a_uint32_t dp = 0; +- a_uint8_t *maddr = NULL; ++ u8 maddr[ETH_ALEN]; + char dp_name[8] = {0}; ++ int ret; + + for (dp = 1; dp <= SSDK_MAX_NR_ETH; dp++) { + snprintf(dp_name, sizeof(dp_name), "dp%d", dp); +@@ -788,11 +789,11 @@ static void ssdk_dt_parse_intf_mac(void) + if (!dp_node) { + continue; + } +- maddr = (a_uint8_t *)of_get_mac_address(dp_node); ++ ret = of_get_mac_address(dp_node, maddr); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) + if (maddr && is_valid_ether_addr(maddr)) { + #else +- if (!IS_ERR(maddr) && is_valid_ether_addr(maddr)) { ++ if (!ret && is_valid_ether_addr(maddr)) { + #endif + ssdk_dt_global.num_intf_mac++; + ether_addr_copy(ssdk_dt_global.intf_mac[dp-1].uc, maddr); diff --git a/package/qca/qca-ssdk/patches/0008-add-aquantia-phy-id-113CB0.patch b/package/qca/qca-ssdk/patches/0008-add-aquantia-phy-id-113CB0.patch new file mode 100644 index 000000000..fba52635c --- /dev/null +++ b/package/qca/qca-ssdk/patches/0008-add-aquantia-phy-id-113CB0.patch @@ -0,0 +1,37 @@ +From 440ab349813e5aa9dbeddab4d82ab64ff5347c5f Mon Sep 17 00:00:00 2001 +From: Dirk Buchwalder +Date: Sat, 30 Oct 2021 19:51:06 +0200 +Subject: [PATCH] add aquantia phy id 113CB0 / 0x31c31C12 + +This adds support for the AQR113C with the id +"113CB0 / 0x31c31C12" to the ssdk. + +This is used in the QNAP 301w + +Signed-off-by: Dirk Buchwalder + +--- + include/hsl/phy/hsl_phy.h | 1 + + src/hsl/phy/hsl_phy.c | 1 + + 2 files changed, 2 insertions(+) + +--- a/include/hsl/phy/hsl_phy.h ++++ b/include/hsl/phy/hsl_phy.h +@@ -579,6 +579,7 @@ typedef struct { + #define AQUANTIA_PHY_112 0x03a1b660 + #define AQUANTIA_PHY_113C_A0 0x31c31C10 + #define AQUANTIA_PHY_113C_A1 0x31c31C11 ++#define AQUANTIA_PHY_113C_B0 0x31c31C12 + #define AQUANTIA_PHY_112C 0x03a1b792 + + #define PHY_805XV2 0x004DD082 +--- a/src/hsl/phy/hsl_phy.c ++++ b/src/hsl/phy/hsl_phy.c +@@ -235,6 +235,7 @@ phy_type_t hsl_phytype_get_by_phyid(a_ui + case AQUANTIA_PHY_112: + case AQUANTIA_PHY_113C_A0: + case AQUANTIA_PHY_113C_A1: ++ case AQUANTIA_PHY_113C_B0: + case AQUANTIA_PHY_112C: + phytype = AQUANTIA_PHY_CHIP; + break; diff --git a/package/qca/qca-ssdk/patches/0009-qca8081-convert-to-5.11-IRQ-model.patch b/package/qca/qca-ssdk/patches/0009-qca8081-convert-to-5.11-IRQ-model.patch new file mode 100644 index 000000000..b0c272b17 --- /dev/null +++ b/package/qca/qca-ssdk/patches/0009-qca8081-convert-to-5.11-IRQ-model.patch @@ -0,0 +1,83 @@ +From 25ff0ae02accadd7b05f1dae788505f833d5c019 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 24 Dec 2021 20:02:32 +0100 +Subject: [PATCH] qca8081: convert to 5.11 IRQ model + +Kernel 5.11 introduced new IRQ handling model for PHY-s, +so provide those if 5.11 or later is used. + +Signed-off-by: Robert Marko +--- + src/hsl/phy/qca808x.c | 46 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 46 insertions(+) + +--- a/src/hsl/phy/qca808x.c ++++ b/src/hsl/phy/qca808x.c +@@ -238,6 +238,7 @@ static int qca808x_config_intr(struct ph + return err; + } + ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)) + static int qca808x_ack_interrupt(struct phy_device *phydev) + { + int err; +@@ -257,6 +258,47 @@ static int qca808x_ack_interrupt(struct + + return (err < 0) ? err : 0; + } ++#endif ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 11, 0)) ++static irqreturn_t qca808x_handle_interrupt(struct phy_device *phydev) ++{ ++ a_uint16_t irq_status, int_enabled; ++ a_uint32_t dev_id = 0, phy_id = 0; ++ qca808x_priv *priv = phydev->priv; ++ const struct qca808x_phy_info *pdata = priv->phy_info; ++ ++ if (!pdata) { ++ return SW_FAIL; ++ } ++ ++ dev_id = pdata->dev_id; ++ phy_id = pdata->phy_addr; ++ ++ irq_status = qca808x_phy_reg_read(dev_id, phy_id, ++ QCA808X_PHY_INTR_STATUS); ++ if (irq_status < 0) { ++ phy_error(phydev); ++ return IRQ_NONE; ++ } ++ ++ /* Read the current enabled interrupts */ ++ int_enabled = qca808x_phy_reg_read(dev_id, phy_id, ++ QCA808X_PHY_INTR_MASK); ++ if (int_enabled < 0) { ++ phy_error(phydev); ++ return IRQ_NONE; ++ } ++ ++ /* See if this was one of our enabled interrupts */ ++ if (!(irq_status & int_enabled)) ++ return IRQ_NONE; ++ ++ phy_trigger_machine(phydev); ++ ++ return IRQ_HANDLED; ++} ++#endif + + /* switch linux negtiation capability to fal avariable */ + #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) +@@ -559,7 +601,11 @@ struct phy_driver qca808x_phy_driver = { + .config_intr = qca808x_config_intr, + .config_aneg = qca808x_config_aneg, + .aneg_done = qca808x_aneg_done, ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)) + .ack_interrupt = qca808x_ack_interrupt, ++#else ++ .handle_interrupt = qca808x_handle_interrupt, ++#endif + .read_status = qca808x_read_status, + .suspend = qca808x_suspend, + .resume = qca808x_resume, diff --git a/package/qca/qca-ssdk/patches/0012-include-fix-compilation-error-for-parse_uci_option.patch b/package/qca/qca-ssdk/patches/0012-include-fix-compilation-error-for-parse_uci_option.patch new file mode 100644 index 000000000..01b8deda9 --- /dev/null +++ b/package/qca/qca-ssdk/patches/0012-include-fix-compilation-error-for-parse_uci_option.patch @@ -0,0 +1,27 @@ +From 8e3500df074625b3eb3a8ed4e8e0b1b116f13d0c Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sat, 7 May 2022 19:03:55 +0200 +Subject: [PATCH] include: fix compilation error for parse_uci_option + +Fix missing include for parse_uci_option + +Signed-off-by: Ansuel Smith +--- + include/ref/ref_uci.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/ref/ref_uci.h b/include/ref/ref_uci.h +index a42ea153..0906c5ba 100755 +--- a/include/ref/ref_uci.h ++++ b/include/ref/ref_uci.h +@@ -19,6 +19,7 @@ + extern "C" { + #endif /* __cplusplus */ + ++#include + + #if defined(IN_SWCONFIG) + int +-- +2.34.1 + diff --git a/rules.mk b/rules.mk index 0463b02c2..d53f673d4 100644 --- a/rules.mk +++ b/rules.mk @@ -62,7 +62,6 @@ ARCH_PACKAGES:=$(call qstrip,$(CONFIG_TARGET_ARCH_PACKAGES)) BOARD:=$(call qstrip,$(CONFIG_TARGET_BOARD)) SUBTARGET:=$(call qstrip,$(CONFIG_TARGET_SUBTARGET)) TARGET_OPTIMIZATION:=$(call qstrip,$(CONFIG_TARGET_OPTIMIZATION)) -export EXTRA_OPTIMIZATION:=$(filter-out -fno-plt,$(call qstrip,$(CONFIG_EXTRA_OPTIMIZATION))) TARGET_SUFFIX=$(call qstrip,$(CONFIG_TARGET_SUFFIX)) BUILD_SUFFIX:=$(call qstrip,$(CONFIG_BUILD_SUFFIX)) SUBDIR:=$(patsubst $(TOPDIR)/%,%,${CURDIR}) @@ -110,7 +109,7 @@ $(foreach t,$(DEFAULT_SUBDIR_TARGETS) $(1), ) endef -DL_DIR:=$(if $(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(TOPDIR)/dl) +DL_DIR=$(if $(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(TOPDIR)/dl)$(if $(DL_SUBDIR),/$(DL_SUBDIR)) OUTPUT_DIR:=$(if $(call qstrip,$(CONFIG_BINARY_FOLDER)),$(call qstrip,$(CONFIG_BINARY_FOLDER)),$(TOPDIR)/bin) BIN_DIR:=$(OUTPUT_DIR)/targets/$(BOARD)/$(SUBTARGET) INCLUDE_DIR:=$(TOPDIR)/include @@ -138,11 +137,7 @@ else endif ifeq ($(or $(CONFIG_EXTERNAL_TOOLCHAIN),$(CONFIG_TARGET_uml)),) - ifeq ($(CONFIG_GCC_USE_IREMAP),y) - iremap = -iremap$(1):$(2) - else - iremap = -f$(if $(CONFIG_REPRODUCIBLE_DEBUG_INFO),file,macro)-prefix-map=$(1)=$(2) - endif + iremap = -f$(if $(CONFIG_REPRODUCIBLE_DEBUG_INFO),file,macro)-prefix-map=$(1)=$(2) endif PACKAGE_DIR:=$(BIN_DIR)/packages @@ -189,7 +184,7 @@ ifndef DUMP -include $(TOOLCHAIN_DIR)/info.mk export GCC_HONOUR_COPTS:=0 TARGET_CROSS:=$(if $(TARGET_CROSS),$(TARGET_CROSS),$(OPTIMIZE_FOR_CPU)-openwrt-linux$(if $(TARGET_SUFFIX),-$(TARGET_SUFFIX))-) - TARGET_CFLAGS+= -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result + TARGET_CFLAGS+= -fhonour-copts TARGET_CPPFLAGS+= -I$(TOOLCHAIN_DIR)/usr/include ifeq ($(CONFIG_USE_MUSL),y) TARGET_CPPFLAGS+= -I$(TOOLCHAIN_DIR)/include/fortify @@ -213,7 +208,6 @@ ifndef DUMP ifneq ($(TOOLCHAIN_LIB_DIRS),) TARGET_LDFLAGS+= $(patsubst %,-L%,$(TOOLCHAIN_LIB_DIRS)) endif - TARGET_PATH:=$(TOOLCHAIN_DIR)/bin:$(TARGET_PATH) endif endif endif @@ -244,23 +238,17 @@ export PKG_CONFIG HOSTCC:=gcc HOSTCXX:=g++ HOST_CPPFLAGS:=-I$(STAGING_DIR_HOST)/include $(if $(IS_PACKAGE_BUILD),-I$(STAGING_DIR_HOSTPKG)/include -I$(STAGING_DIR)/host/include) +HOST_CXXFLAGS:= HOST_CFLAGS:=-O2 $(HOST_CPPFLAGS) HOST_LDFLAGS:=-L$(STAGING_DIR_HOST)/lib $(if $(IS_PACKAGE_BUILD),-L$(STAGING_DIR_HOSTPKG)/lib -L$(STAGING_DIR)/host/lib) -ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),) - TARGET_AR:=$(TARGET_CROSS)gcc-ar - TARGET_RANLIB:=$(TARGET_CROSS)gcc-ranlib - TARGET_NM:=$(TARGET_CROSS)gcc-nm -else - TARGET_AR:=$(TARGET_CROSS)ar - TARGET_RANLIB:=$(TARGET_CROSS)ranlib - TARGET_NM:=$(TARGET_CROSS)nm -endif - BUILD_KEY=$(TOPDIR)/key-build FAKEROOT:=$(STAGING_DIR_HOST)/bin/fakeroot +TARGET_AR:=$(TARGET_CROSS)gcc-ar +TARGET_RANLIB:=$(TARGET_CROSS)gcc-ranlib +TARGET_NM:=$(TARGET_CROSS)gcc-nm TARGET_CC:=$(TARGET_CROSS)gcc TARGET_CXX:=$(TARGET_CROSS)g++ KPATCH:=$(SCRIPT_DIR)/patch-kernel.sh @@ -269,9 +257,6 @@ ESED:=$(STAGING_DIR_HOST)/bin/sed -E -i -e MKHASH:=$(STAGING_DIR_HOST)/bin/mkhash # MKHASH is used in /scripts, so we export it here. export MKHASH -# DOWNLOAD_CHECK_CERTIFICATE is used in /scripts, so we export it here. -DOWNLOAD_CHECK_CERTIFICATE:=$(CONFIG_DOWNLOAD_CHECK_CERTIFICATE) -export DOWNLOAD_CHECK_CERTIFICATE CP:=cp -fpR LN:=ln -sf XARGS:=xargs -r @@ -424,7 +409,7 @@ $(shell \ if git log -1 >/dev/null 2>/dev/null; then \ if [ -n "$(1)" ]; then \ last_bump="$$(git log --pretty=format:'%h %s' . | \ - grep --max-count=1 -e ': [uU]pdate to ' -e ': [bB]ump to ' | \ + grep -m 1 -e ': [uU]pdate to ' -e ': [bB]ump to ' | \ cut -f 1 -d ' ')"; \ fi; \ if [ -n "$$last_bump" ]; then \ diff --git a/scripts/download.pl b/scripts/download.pl index a73c9d1bc..9a0f48f38 100755 --- a/scripts/download.pl +++ b/scripts/download.pl @@ -249,16 +249,14 @@ foreach my $mirror (@ARGV) { } elsif ($mirror =~ /^\@OPENWRT$/) { # use OpenWrt source server directly } elsif ($mirror =~ /^\@DEBIAN\/(.+)$/) { + push @mirrors, "https://mirrors.aliyun.com/debian/$1"; push @mirrors, "https://mirrors.tencent.com/debian/$1"; - push @mirrors, "https://mirrors.tuna.tsinghua.edu.cn/debian/$1"; - push @mirrors, "https://mirrors.ustc.edu.cn/debian/$1"; push @mirrors, "https://ftp.debian.org/debian/$1"; push @mirrors, "https://mirror.leaseweb.com/debian/$1"; push @mirrors, "https://mirror.netcologne.de/debian/$1"; } elsif ($mirror =~ /^\@APACHE\/(.+)$/) { - push @mirrors, "https://mirrors.cloud.tencent.com/apache/$1"; - push @mirrors, "https://mirrors.tuna.tsinghua.edu.cn/apache/$1"; - push @mirrors, "https://mirrors.ustc.edu.cn/apache/$1"; + push @mirrors, "https://mirrors.aliyun.com/apache/$1"; + push @mirrors, "https://mirrors.tencent.com/apache/$1"; push @mirrors, "https://mirror.netcologne.de/apache.org/$1"; push @mirrors, "https://mirror.aarnet.edu.au/pub/apache/$1"; push @mirrors, "https://mirror.csclub.uwaterloo.ca/apache/$1"; @@ -274,8 +272,8 @@ foreach my $mirror (@ARGV) { push @mirrors, "https://raw.githubusercontent.com/$1"; } } elsif ($mirror =~ /^\@GNU\/(.+)$/) { - push @mirrors, "https://mirrors.tuna.tsinghua.edu.cn/gnu/$1"; - push @mirrors, "https://mirrors.ustc.edu.cn/gnu/$1"; + push @mirrors, "https://mirrors.aliyun.com/gnu/$1"; + push @mirrors, "https://mirrors.tencent.com/gnu/$1"; push @mirrors, "https://mirror.csclub.uwaterloo.ca/gnu/$1"; push @mirrors, "https://mirror.netcologne.de/gnu/$1"; push @mirrors, "http://ftp.kddilabs.jp/GNU/gnu/$1"; @@ -301,7 +299,7 @@ foreach my $mirror (@ARGV) { push @extra, "$extra[0]/longterm/v$1"; } foreach my $dir (@extra) { - push @mirrors, "https://mirrors.tuna.tsinghua.edu.cn/kernel/$dir"; + push @mirrors, "https://mirror.iscas.ac.cn/kernel.org/$dir"; push @mirrors, "https://mirrors.ustc.edu.cn/kernel.org/$dir"; push @mirrors, "https://cdn.kernel.org/pub/$dir"; push @mirrors, "https://download.xs4all.nl/ftp.kernel.org/pub/$dir"; diff --git a/scripts/gen-rddependencies.sh b/scripts/gen-rddependencies.sh new file mode 100755 index 000000000..509d6a4fa --- /dev/null +++ b/scripts/gen-rddependencies.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +TARGETS=$* +READELF="${READELF:-readelf}" +XARGS="${XARGS:-xargs -r}" + +find $TARGETS -type f -a -exec file {} \; | \ + sed -n -e 's/^\(.*\):.*ELF.*\(executable\|shared object\).*,.*/\1/p' | \ + $XARGS -n1 $READELF -l | grep 'Requesting' | cut -d':' -f2 | tr -d ' ]' | \ + $XARGS basename + +cd `dirname ${0}` +./gen-dependencies.sh ${TARGETS} diff --git a/scripts/linksys-image.sh b/scripts/linksys-image.sh index 3b4412c06..d251b5da8 100755 --- a/scripts/linksys-image.sh +++ b/scripts/linksys-image.sh @@ -17,7 +17,6 @@ # Padding ('0' + 0x20 *7) (8 bytes) # Signature of signer. Not checked so use arbitrary value (16 bytes) # Padding (0x00) (192 bytes) -# 0x0A (1 byte) ## version history # * version 1: initial commit @@ -62,6 +61,4 @@ printf ".LINKSYS.01000409%-15s%-8s%-8s%-16s" "${TYPE}" "${CRC}" "0" "K0000000F02 dd if=/dev/zero bs=1 count=192 conv=notrunc >> "${IMG_TMP_OUT}" -printf '\12' >> "${IMG_TMP_OUT}" - cp "${IMG_TMP_OUT}" "${IMG_OUT}" diff --git a/scripts/sercomm-kernel.sh b/scripts/sercomm-kernel.sh new file mode 100755 index 000000000..6ce3086c9 --- /dev/null +++ b/scripts/sercomm-kernel.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (c) 2021 Mikhail Zhilkin +# +### +### sercomm-kernel.sh - calculates and appends a special kernel header. +### Intended for some Sercomm devices (e.g., Beeline +### SmartBox GIGA, Beeline SmartBox Turbo+, Sercomm +### S3). +# +# Credits to @kar200 for the header description. More details are here: +# https://forum.openwrt.org/t/add-support-for-sercomm-s3-on-stock-uboot +# +if [ $# -ne 3 ]; then + echo "SYNTAX: $0 " + exit 1 +fi + +FILE_TMP=$1.shdr +KERNEL_IMG=$1 +KERNEL_OFFSET=$2 +ROOTFS_OFFSET=$3 + +# Sercomm HDR (0x53657200), 0xffffffff for hdr crc32 calc +hdr_sign_offs=0x0 +hdr_sign_val=0x53657200 +# Absoulte lenght for Sercomm footer +hdr_footer_size_offs=0x4 +hdr_footer_size_val= +# Header checksum. 0xffffffff for hdr crc32 calc +hdr_head_chksum_offs=0x8 +hdr_head_chksum_val= +# Magic constant (0x2ffffff) +hdr_int04_offs=0xc +hdr_int04_val=0x2ffffff +# Kernel flash offset +hdr_kern_offs_offs=0x10 +hdr_kern_offs_val=$KERNEL_OFFSET +# Kernel lenght +hdr_kern_len_offs=0x14 +hdr_kern_len_val= +# Kernel checksum +hdr_kern_chksum_offs=0x18 +hdr_kern_chksum_val= +# Magic constant (0x0) +hdr_int08_offs=0x1c +hdr_int08_val=0x0 +# Rootfs flash offset +hdr_rootfs_offs_offs=0x28 +hdr_rootfs_offs_val=$ROOTFS_OFFSET +# Rootfs flash lenght. We're checking only first 4 bytes +hdr_rootfs_len_offs=0x2c +hdr_rootfs_len_val=0x4 +# Rootfs checksum. Checksum is a constant for UBI (first 4 bytes) +hdr_rootfs_chksum_offs=0x30 +hdr_rootfs_chksum_val=0x1cfc552d +# Magic constant (0x0) +hdr_int10_offs=0x34 +hdr_int10_val=0x0 + +pad_zeros () { + awk '{ printf "%8s\n", $0 }' | sed 's/ /0/g' +} + +# Remove leading 0x +trim_hx () { + printf "%x\n" $1 | pad_zeros +} + +# Change endian +swap_hx () { + pad_zeros | awk '{for (i=7;i>=1;i=i-2) printf "%s%s", \ + substr($1,i,2), (i>1?"":"\n")}' +} + +# Check file size +fsize () { + printf "%x\n" `stat -c "%s" $1` +} + +# Calculate checksum +chksum () { + dd if=$1 2>/dev/null | gzip -c | tail -c 8 | od -An -tx4 -N4 \ + --endian=big | tr -d ' \n' | pad_zeros +} + +# Write 4 bytes in the header by offset +write_hdr () { + echo -ne "$(echo $1 | sed 's/../\\x&/g')" | dd of=$FILE_TMP bs=1 \ + seek=$(($2)) count=4 conv=notrunc status=none 2>/dev/null +} + +# Pad a new header with 0xff +dd if=/dev/zero ibs=1 count=256 status=none | tr "\000" "\377" > \ + $FILE_TMP 2>/dev/null + +# Write constants +write_hdr $(trim_hx $hdr_int04_val) $hdr_int04_offs +write_hdr $(trim_hx $hdr_int08_val) $hdr_int08_offs +write_hdr $(trim_hx $hdr_int10_val) $hdr_int10_offs +# Write footer data +hdr_footer_size_val=$(($hdr_rootfs_offs_val + $hdr_rootfs_len_val)) +write_hdr $(trim_hx $hdr_footer_size_val | swap_hx) $hdr_footer_size_offs +# Write kernel data +write_hdr $(trim_hx $hdr_kern_offs_val | swap_hx) $hdr_kern_offs_offs +hdr_kern_len_val=$(fsize $KERNEL_IMG | pad_zeros) +write_hdr $(echo $hdr_kern_len_val | swap_hx) $hdr_kern_len_offs +hdr_kern_chksum_val=$(chksum $KERNEL_IMG) +write_hdr $hdr_kern_chksum_val $hdr_kern_chksum_offs +# Write rootfs data +write_hdr $(trim_hx $hdr_rootfs_offs_val | swap_hx) $hdr_rootfs_offs_offs +write_hdr $(trim_hx $hdr_rootfs_len_val | swap_hx) $hdr_rootfs_len_offs +write_hdr $(trim_hx $hdr_rootfs_chksum_val) $hdr_rootfs_chksum_offs +# Write header checksum +hdr_head_chksum_val=$(chksum $FILE_TMP) +write_hdr $hdr_head_chksum_val $hdr_head_chksum_offs +# Place Sercomm signature +write_hdr $(trim_hx $hdr_sign_val) $hdr_sign_offs + +dd if=$KERNEL_IMG >> $FILE_TMP +mv $FILE_TMP $KERNEL_IMG diff --git a/scripts/target-metadata.pl b/scripts/target-metadata.pl index e1d4ef242..223b5aaec 100755 --- a/scripts/target-metadata.pl +++ b/scripts/target-metadata.pl @@ -179,7 +179,7 @@ EOF print <> $(PKG_BUILD_DIR)/repositories.conf echo '## This is the local package repository, do not remove!' >> $(PKG_BUILD_DIR)/repositories.conf echo 'src imagebuilder file:packages' >> $(PKG_BUILD_DIR)/repositories.conf +ifeq ($(CONFIG_BUILDBOT),) ifeq ($(CONFIG_IB_STANDALONE),) $(FIND) $(call FeedPackageDir,libc) -type f \ \( -name 'libc_*.ipk' -or -name 'kernel_*.ipk' -or -name 'kmod-*.ipk' \) \ @@ -74,7 +78,7 @@ ifneq ($(CONFIG_SIGNATURE_CHECK),) $(CP) -L $(STAGING_DIR_ROOT)/usr/sbin/opkg-key $(PKG_BUILD_DIR)/scripts/ endif - $(CP) $(TOPDIR)/target/linux $(PKG_BUILD_DIR)/target/ + $(CP) -L $(TOPDIR)/target/linux $(PKG_BUILD_DIR)/target/ if [ -d $(TOPDIR)/staging_dir/host/lib/grub ]; then \ $(CP) $(TOPDIR)/staging_dir/host/lib/grub/ $(PKG_BUILD_DIR)/staging_dir/host/lib; \ fi diff --git a/target/imagebuilder/files/Makefile b/target/imagebuilder/files/Makefile index aeae98aac..3329fe70a 100644 --- a/target/imagebuilder/files/Makefile +++ b/target/imagebuilder/files/Makefile @@ -27,6 +27,7 @@ include $(INCLUDE_DIR)/rootfs.mk include $(INCLUDE_DIR)/version.mk export REVISION +export SOURCE_DATE_EPOCH define Helptext Available Commands: @@ -102,6 +103,7 @@ staging_dir/host/.prereq-build: include/prereq-build.mk _call_info: FORCE echo 'Current Target: "$(TARGETID)"' + echo 'Current Architecture: "$(ARCH)"' echo 'Current Revision: "$(REVISION)"' echo 'Default Packages: $(DEFAULT_PACKAGES)' echo 'Available Profiles:' diff --git a/target/imagebuilder/files/README.md b/target/imagebuilder/files/README.md new file mode 100644 index 000000000..9a9616d06 --- /dev/null +++ b/target/imagebuilder/files/README.md @@ -0,0 +1,11 @@ +# ./packages folder + +Add `.ipk` packages to this folder will allow the ImageBuilder to install them. + +For more complex setups consider adding a custom feed containing packages. + + src custom file:///path/to/packages + +Whenever the ImageBuilder builds a firmware image this folder will be reloaded +and a new package index created. In case signature checks are enabled the +`./packages/Packages` index will be signed with a locally generated key pair. diff --git a/target/linux/rockchip/image/armv8.mk b/target/linux/rockchip/image/armv8.mk index 744fff079..73cf601f7 100644 --- a/target/linux/rockchip/image/armv8.mk +++ b/target/linux/rockchip/image/armv8.mk @@ -130,7 +130,7 @@ define Device/friendlyarm_nanopi-r5c IMAGE/sysupgrade.img.gz := boot-common | boot-script nanopi-r5s | pine64-img | gzip | append-metadata DEVICE_PACKAGES := kmod-r8125 endef -TARGET_DEVICES += friendlyarm_nanopi-r5c +#TARGET_DEVICES += friendlyarm_nanopi-r5c define Device/firefly_station-p2 DEVICE_VENDOR := Firefly diff --git a/target/llvm-bpf/Makefile b/target/llvm-bpf/Makefile new file mode 100644 index 000000000..6cadf693e --- /dev/null +++ b/target/llvm-bpf/Makefile @@ -0,0 +1,30 @@ +# +# Copyright (C) 2021 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +override MAKEFLAGS= + +LLVM_VERSION := $(shell cat $(STAGING_DIR_HOST)/llvm-bpf/.llvm-version) + +LLVM_BPF_PREFIX := llvm-bpf-$(LLVM_VERSION).$(HOST_OS)-$(HOST_ARCH) +LLVM_TAR := $(BIN_DIR)/$(LLVM_BPF_PREFIX).tar.xz + +$(LLVM_TAR): $(STAGING_DIR_HOST)/llvm-bpf/.llvm-version + tar -C $(STAGING_DIR_HOST) \ + -I '$(STAGING_DIR_HOST)/bin/xz -7e -T$(if $(filter 1,$(NPROC)),2,0)' \ + $(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \ + -cf $@.tmp llvm-bpf $(LLVM_BPF_PREFIX) + mv $@.tmp $@ + +download: +prepare: +compile: $(LLVM_TAR) +install: compile + +clean: + rm -f $(LLVM_TAR) diff --git a/target/sdk/Config.in b/target/sdk/Config.in index 0c8a61d24..1984e242e 100644 --- a/target/sdk/Config.in +++ b/target/sdk/Config.in @@ -7,4 +7,11 @@ config SDK with a precompiled toolchain. It can be used to develop and test packages for OpenWrt before including them in the buildroot - +config SDK_LLVM_BPF + bool "Build the LLVM-BPF toolchain tarball" + depends on BPF_TOOLCHAIN_BUILD_LLVM + default BUILDBOT + help + This is a tarball of the precompiled LLVM toolchain suitable + for unpacking into the buildroot/SDK. It is used to build packages + that ship with eBPF kernel modules diff --git a/target/sdk/Makefile b/target/sdk/Makefile index 060662119..be7e1ebf5 100644 --- a/target/sdk/Makefile +++ b/target/sdk/Makefile @@ -82,6 +82,18 @@ KERNEL_FILES_BASE := \ KERNEL_FILES := $(patsubst $(TOPDIR)/%,%,$(wildcard $(addprefix $(LINUX_DIR)/,$(KERNEL_FILES_BASE)))) +# The kernel source hosts various userspace utilities sources. +# These are packaged separately from the kernel and kernel modules. +# The source has to be included here to be buildable by the SDK. +# +USERSPACE_UTILS_FILES := \ + tools/build \ + tools/scripts \ + tools/usb/usbip \ + tools/spi + +USERSPACE_FILES := $(patsubst $(TOPDIR)/%,%,$(wildcard $(addprefix $(LINUX_DIR)/,$(USERSPACE_UTILS_FILES)))) + all: compile $(BIN_DIR)/$(SDK_NAME).tar.xz: clean @@ -100,8 +112,7 @@ $(BIN_DIR)/$(SDK_NAME).tar.xz: clean $(SDK_DIRS) $(KERNEL_FILES) | \ $(TAR) -xf - -C $(SDK_BUILD_DIR) - # Copy usbip sources, this is required for the usbip userspace packages to be buildable by the SDK. - $(TAR) -cf - -C $(TOPDIR) $(KDIR_BASE)/tools/usb/usbip/ | \ + $(TAR) -cf - -C $(TOPDIR) $(USERSPACE_FILES) | \ $(TAR) -xf - -C $(SDK_BUILD_DIR) (cd $(SDK_BUILD_DIR); find $(STAGING_SUBDIR_HOST)/bin $(STAGING_SUBDIR_HOST)/usr/bin \ diff --git a/target/sdk/files/Config.in b/target/sdk/files/Config.in index f68799249..12c0f6a62 100644 --- a/target/sdk/files/Config.in +++ b/target/sdk/files/Config.in @@ -31,7 +31,6 @@ menu "Global build settings" choice prompt "Binary stripping method" - default USE_STRIP if EXTERNAL_TOOLCHAIN default USE_STRIP if USE_GLIBC default USE_SSTRIP help @@ -130,7 +129,7 @@ config IN_SDK config MODULES bool default y - option modules + modules source "Config-build.in" source "tmp/.config-package.in" diff --git a/target/sdk/files/Makefile b/target/sdk/files/Makefile index 2f89ce0cf..dca8bbe20 100644 --- a/target/sdk/files/Makefile +++ b/target/sdk/files/Makefile @@ -14,7 +14,7 @@ export TOPDIR LC_ALL LANG SDK world: -DISTRO_PKG_CONFIG:=$(shell which -a pkg-config | grep -E '\/usr' | head -n 1) +DISTRO_PKG_CONFIG:=$(shell $(TOPDIR)/scripts/command_all.sh pkg-config | grep '/usr' -m 1) export PATH:=$(TOPDIR)/staging_dir/host/bin:$(PATH) ifneq ($(OPENWRT_BUILD),1) diff --git a/target/toolchain/Config.in b/target/toolchain/Config.in index 5a6ecefeb..02c486b32 100644 --- a/target/toolchain/Config.in +++ b/target/toolchain/Config.in @@ -1,6 +1,7 @@ config MAKE_TOOLCHAIN bool "Package the OpenWrt-based Toolchain" depends on !EXTERNAL_TOOLCHAIN + default BUILDBOT help Package the created toolchain as a tarball under the bin/ directory as OpenWrt-Toolchain-$(BOARD)-for-$(ARCH)$(ARCH_SUFFIX)-gcc-$(GCCV)$(DIR_SUFFIX). diff --git a/target/toolchain/Makefile b/target/toolchain/Makefile index c3ba70db0..c33bccee6 100644 --- a/target/toolchain/Makefile +++ b/target/toolchain/Makefile @@ -26,7 +26,7 @@ all: compile TOOLCHAIN_PREFIX:=$(TOOLCHAIN_BUILD_DIR)/toolchain-$(ARCH)$(ARCH_SUFFIX)_gcc-$(GCCV)$(DIR_SUFFIX) -$(BIN_DIR)/$(TOOLCHAIN_NAME).tar.bz2: clean +$(BIN_DIR)/$(TOOLCHAIN_NAME).tar.xz: clean mkdir -p $(TOOLCHAIN_BUILD_DIR) $(TAR) -cf - -C $(TOPDIR)/staging_dir/ \ $(foreach exclude,$(EXCLUDE_DIRS),--exclude="$(exclude)") \ @@ -62,13 +62,14 @@ $(BIN_DIR)/$(TOOLCHAIN_NAME).tar.bz2: clean find $(TOOLCHAIN_BUILD_DIR) -name CVS | $(XARGS) rm -rf mkdir -p $(BIN_DIR) (cd $(BUILD_DIR); \ - tar cfj $@ $(TOOLCHAIN_NAME); \ + tar -I '$(STAGING_DIR_HOST)/bin/xz -7e -T$(if $(filter 1,$(NPROC)),2,0)' -cf $@ $(TOOLCHAIN_NAME) \ + --mtime="$(shell date --date=@$(SOURCE_DATE_EPOCH))"; \ ) download: prepare: -compile: $(BIN_DIR)/$(TOOLCHAIN_NAME).tar.bz2 +compile: $(BIN_DIR)/$(TOOLCHAIN_NAME).tar.xz install: compile clean: - rm -rf $(TOOLCHAIN_BUILD_DIR) $(BIN_DIR)/$(TOOLCHAIN_NAME).tar.bz2 + rm -rf $(TOOLCHAIN_BUILD_DIR) $(BIN_DIR)/$(TOOLCHAIN_NAME).tar.xz diff --git a/toolchain/Config.in b/toolchain/Config.in index 2d29ec09e..6d3cc0a20 100644 --- a/toolchain/Config.in +++ b/toolchain/Config.in @@ -37,6 +37,7 @@ menuconfig TARGET_OPTIONS Most people will answer N. + choice BPF_TOOLCHAIN prompt "BPF toolchain" if DEVEL default BPF_TOOLCHAIN_BUILD_LLVM if BUILDBOT @@ -168,6 +169,7 @@ menuconfig EXTERNAL_TOOLCHAIN string prompt "Toolchain include path" if DEVEL depends on EXTERNAL_TOOLCHAIN && !NATIVE_TOOLCHAIN + default "./usr/include ./include/fortify ./include" if EXTERNAL_TOOLCHAIN_LIBC_USE_MUSL default "./usr/include ./include" help Specify additional directories searched for header files (override @@ -307,7 +309,7 @@ config GDB_PYTHON help Enable the python bindings for GDB to allow using python in the gdb shell. - + config HAS_BPF_TOOLCHAIN bool @@ -326,7 +328,7 @@ config USE_LLVM_PREBUILT config USE_LLVM_BUILD default y if !DEVEL && BUILDBOT select HAS_BPF_TOOLCHAIN - bool + bool config USE_GLIBC default y if !TOOLCHAINOPTS && !EXTERNAL_TOOLCHAIN && !NATIVE_TOOLCHAIN && (arc) diff --git a/toolchain/binutils/Config.in b/toolchain/binutils/Config.in index 50829ad36..7fe797a5a 100644 --- a/toolchain/binutils/Config.in +++ b/toolchain/binutils/Config.in @@ -2,7 +2,7 @@ choice prompt "Binutils Version" if TOOLCHAINOPTS - default BINUTILS_USE_VERSION_2_37 + default BINUTILS_USE_VERSION_2_39 help Select the version of binutils you wish to use. @@ -13,7 +13,7 @@ choice config BINUTILS_USE_VERSION_2_38 bool "Binutils 2.38" select BINUTILS_VERSION_2_38 - + config BINUTILS_USE_VERSION_2_39 bool "Binutils 2.39" select BINUTILS_VERSION_2_39 diff --git a/toolchain/binutils/Config.version b/toolchain/binutils/Config.version index 01d4770dd..eac97877f 100644 --- a/toolchain/binutils/Config.version +++ b/toolchain/binutils/Config.version @@ -1,11 +1,12 @@ + config BINUTILS_VERSION_2_37 bool config BINUTILS_VERSION_2_38 - default y if !TOOLCHAINOPTS bool - + config BINUTILS_VERSION_2_39 + default y if !TOOLCHAINOPTS bool config BINUTILS_VERSION diff --git a/toolchain/binutils/patches/2.39/005-ld-fix-NEWS-typos.patch b/toolchain/binutils/patches/2.39/005-ld-fix-NEWS-typos.patch new file mode 100644 index 000000000..39c61d931 --- /dev/null +++ b/toolchain/binutils/patches/2.39/005-ld-fix-NEWS-typos.patch @@ -0,0 +1,27 @@ +From 9284b63ea39cecbfc1522d9e143ecb7727d77eb5 Mon Sep 17 00:00:00 2001 +From: Martin Liska +Date: Mon, 8 Aug 2022 13:22:26 +0200 +Subject: [PATCH 005/160] ld: fix NEWS typos + +ld/ChangeLog: + + * NEWS: Fix 2 typos. +--- + ld/NEWS | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/ld/NEWS ++++ b/ld/NEWS +@@ -27,10 +27,10 @@ Changes in 2.39: + --enable-warn-rwx-segments=no + will make --no-warn-rwx-segments enabled by default. + +- --enable-defaul-execstack=no ++ --enable-default-execstack=no + will stop the creation of an executable stack simply because an input file + is missing a .note.GNU-stack section, even on architectures where this +- ehaviour is the default. ++ behaviour is the default. + + * TYPE= is now supported in an output section description to set the + section type value. diff --git a/toolchain/binutils/patches/2.39/008-gas-Dwarf-properly-skip-zero-size-functions.patch b/toolchain/binutils/patches/2.39/008-gas-Dwarf-properly-skip-zero-size-functions.patch new file mode 100644 index 000000000..055da8412 --- /dev/null +++ b/toolchain/binutils/patches/2.39/008-gas-Dwarf-properly-skip-zero-size-functions.patch @@ -0,0 +1,90 @@ +From e8cf73215187b0c08679d726a5cc7c019fa3ea2e Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Wed, 10 Aug 2022 10:34:22 +0200 +Subject: [PATCH 008/160] gas/Dwarf: properly skip zero-size functions + +PR gas/29451 + +While out_debug_abbrev() properly skips such functions, out_debug_info() +mistakenly didn't. It needs to calculate the high_pc expression ahead of +time, in order to skip emitting any data for the function if the value +is zero. + +The one case which would still leave a zero-size entry is when +symbol_get_obj(symp)->size ends up evaluating to zero. I hope we can +expect that to not be the case, otherwise we'd need to have a way to +post-process .debug_info contents between resolving expressions and +actually writing the data out to the file. Even then it wouldn't be +entirely obvious in which way to alter the data. + +(cherry picked from commit d7abcbcea5ddd40a3bf28758b62f35933c59f996) +--- + gas/dwarf2dbg.c | 39 ++++++++++++++++++++------------------- + 1 file changed, 20 insertions(+), 19 deletions(-) + +--- a/gas/dwarf2dbg.c ++++ b/gas/dwarf2dbg.c +@@ -2882,6 +2882,7 @@ out_debug_info (segT info_seg, segT abbr + { + const char *name; + size_t len; ++ expressionS size = { .X_op = O_constant }; + + /* Skip warning constructs (see above). */ + if (symbol_get_bfdsym (symp)->flags & BSF_WARNING) +@@ -2895,6 +2896,18 @@ out_debug_info (segT info_seg, segT abbr + if (!S_IS_DEFINED (symp) || !S_IS_FUNCTION (symp)) + continue; + ++#if defined (OBJ_ELF) /* || defined (OBJ_MAYBE_ELF) */ ++ size.X_add_number = S_GET_SIZE (symp); ++ if (size.X_add_number == 0 && IS_ELF ++ && symbol_get_obj (symp)->size != NULL) ++ { ++ size.X_op = O_add; ++ size.X_op_symbol = make_expr_symbol (symbol_get_obj (symp)->size); ++ } ++#endif ++ if (size.X_op == O_constant && size.X_add_number == 0) ++ continue; ++ + subseg_set (str_seg, 0); + name_sym = symbol_temp_new_now_octets (); + name = S_GET_NAME (symp); +@@ -2920,29 +2933,17 @@ out_debug_info (segT info_seg, segT abbr + emit_expr (&exp, sizeof_address); + + /* DW_AT_high_pc */ +- exp.X_op = O_constant; +-#if defined (OBJ_ELF) /* || defined (OBJ_MAYBE_ELF) */ +- exp.X_add_number = S_GET_SIZE (symp); +- if (exp.X_add_number == 0 && IS_ELF +- && symbol_get_obj (symp)->size != NULL) +- { +- exp.X_op = O_add; +- exp.X_op_symbol = make_expr_symbol (symbol_get_obj (symp)->size); +- } +-#else +- exp.X_add_number = 0; +-#endif + if (DWARF2_VERSION < 4) + { +- if (exp.X_op == O_constant) +- exp.X_op = O_symbol; +- exp.X_add_symbol = symp; +- emit_expr (&exp, sizeof_address); ++ if (size.X_op == O_constant) ++ size.X_op = O_symbol; ++ size.X_add_symbol = symp; ++ emit_expr (&size, sizeof_address); + } +- else if (exp.X_op == O_constant) +- out_uleb128 (exp.X_add_number); ++ else if (size.X_op == O_constant) ++ out_uleb128 (size.X_add_number); + else +- emit_leb128_expr (symbol_get_value_expression (exp.X_op_symbol), 0); ++ emit_leb128_expr (symbol_get_value_expression (size.X_op_symbol), 0); + } + + /* End of children. */ diff --git a/toolchain/binutils/patches/2.39/009-PR29462-internal-error-in-relocate-at-powerpc.cc-107.patch b/toolchain/binutils/patches/2.39/009-PR29462-internal-error-in-relocate-at-powerpc.cc-107.patch new file mode 100644 index 000000000..e325d3bcb --- /dev/null +++ b/toolchain/binutils/patches/2.39/009-PR29462-internal-error-in-relocate-at-powerpc.cc-107.patch @@ -0,0 +1,270 @@ +From e3b5d935247084dca057dea72be61b063fe2357a Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Wed, 10 Aug 2022 10:38:52 +0930 +Subject: [PATCH 009/160] PR29462, internal error in relocate, at + powerpc.cc:10796 + +Prior to the inline plt call support (commit 08be322439), the only +local syms with plt entries were local ifunc symbols. There shouldn't +be stubs for other local symbols so don't look for them. The patch +also fixes minor bugs in get_reference_flags; Many relocs are valid +only for ppc64 and a couple only for ppc32. + + PR 29462 + * powerpc.cc (Target_powerpc::Relocate::relocate): Rename + use_plt_offset to pltcal_to_direct, invert logic. For relocs + not used with inline plt sequences against local symbols, only + look for stubs when the symbol is an ifunc. + (Target_powerpc::Scan::get_reference_flags): Correct reloc + handling for relocs not valid for both 32-bit and 64-bit. + +(cherry picked from commit 6158b25f77db11712b84e6a4609898f2615ac749) +--- + gold/powerpc.cc | 129 ++++++++++++++++++++++++++++-------------------- + 1 file changed, 75 insertions(+), 54 deletions(-) + +--- a/gold/powerpc.cc ++++ b/gold/powerpc.cc +@@ -7675,22 +7675,18 @@ Target_powerpc::Scan:: + + switch (r_type) + { ++ case elfcpp::R_PPC64_TOC: ++ if (size != 64) ++ break; ++ // Fall through. + case elfcpp::R_POWERPC_NONE: + case elfcpp::R_POWERPC_GNU_VTINHERIT: + case elfcpp::R_POWERPC_GNU_VTENTRY: +- case elfcpp::R_PPC64_TOC: + // No symbol reference. + break; + + case elfcpp::R_PPC64_ADDR64: + case elfcpp::R_PPC64_UADDR64: +- case elfcpp::R_POWERPC_ADDR32: +- case elfcpp::R_POWERPC_UADDR32: +- case elfcpp::R_POWERPC_ADDR16: +- case elfcpp::R_POWERPC_UADDR16: +- case elfcpp::R_POWERPC_ADDR16_LO: +- case elfcpp::R_POWERPC_ADDR16_HI: +- case elfcpp::R_POWERPC_ADDR16_HA: + case elfcpp::R_PPC64_ADDR16_HIGHER34: + case elfcpp::R_PPC64_ADDR16_HIGHERA34: + case elfcpp::R_PPC64_ADDR16_HIGHEST34: +@@ -7700,6 +7696,16 @@ Target_powerpc::Scan:: + case elfcpp::R_PPC64_D34_HI30: + case elfcpp::R_PPC64_D34_HA30: + case elfcpp::R_PPC64_D28: ++ if (size != 64) ++ break; ++ // Fall through. ++ case elfcpp::R_POWERPC_ADDR32: ++ case elfcpp::R_POWERPC_UADDR32: ++ case elfcpp::R_POWERPC_ADDR16: ++ case elfcpp::R_POWERPC_UADDR16: ++ case elfcpp::R_POWERPC_ADDR16_LO: ++ case elfcpp::R_POWERPC_ADDR16_HI: ++ case elfcpp::R_POWERPC_ADDR16_HA: + ref = Symbol::ABSOLUTE_REF; + break; + +@@ -7710,13 +7716,14 @@ Target_powerpc::Scan:: + ref = Symbol::FUNCTION_CALL | Symbol::ABSOLUTE_REF; + break; + +- case elfcpp::R_PPC64_REL64: +- case elfcpp::R_POWERPC_REL32: + case elfcpp::R_PPC_LOCAL24PC: +- case elfcpp::R_POWERPC_REL16: +- case elfcpp::R_POWERPC_REL16_LO: +- case elfcpp::R_POWERPC_REL16_HI: +- case elfcpp::R_POWERPC_REL16_HA: ++ if (size != 32) ++ break; ++ // Fall through. ++ ref = Symbol::RELATIVE_REF; ++ break; ++ ++ case elfcpp::R_PPC64_REL64: + case elfcpp::R_PPC64_REL16_HIGH: + case elfcpp::R_PPC64_REL16_HIGHA: + case elfcpp::R_PPC64_REL16_HIGHER: +@@ -7729,36 +7736,45 @@ Target_powerpc::Scan:: + case elfcpp::R_PPC64_REL16_HIGHEST34: + case elfcpp::R_PPC64_REL16_HIGHESTA34: + case elfcpp::R_PPC64_PCREL28: ++ if (size != 64) ++ break; ++ // Fall through. ++ case elfcpp::R_POWERPC_REL32: ++ case elfcpp::R_POWERPC_REL16: ++ case elfcpp::R_POWERPC_REL16_LO: ++ case elfcpp::R_POWERPC_REL16_HI: ++ case elfcpp::R_POWERPC_REL16_HA: + ref = Symbol::RELATIVE_REF; + break; + ++ case elfcpp::R_PPC_PLTREL24: ++ if (size != 32) ++ break; ++ ref = Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF; ++ break; ++ + case elfcpp::R_PPC64_REL24_NOTOC: +- if (size == 32) ++ case elfcpp::R_PPC64_REL24_P9NOTOC: ++ case elfcpp::R_PPC64_PLT16_LO_DS: ++ case elfcpp::R_PPC64_PLTSEQ_NOTOC: ++ case elfcpp::R_PPC64_PLTCALL_NOTOC: ++ case elfcpp::R_PPC64_PLT_PCREL34: ++ case elfcpp::R_PPC64_PLT_PCREL34_NOTOC: ++ if (size != 64) + break; + // Fall through. +- case elfcpp::R_PPC64_REL24_P9NOTOC: + case elfcpp::R_POWERPC_REL24: +- case elfcpp::R_PPC_PLTREL24: + case elfcpp::R_POWERPC_REL14: + case elfcpp::R_POWERPC_REL14_BRTAKEN: + case elfcpp::R_POWERPC_REL14_BRNTAKEN: + case elfcpp::R_POWERPC_PLT16_LO: + case elfcpp::R_POWERPC_PLT16_HI: + case elfcpp::R_POWERPC_PLT16_HA: +- case elfcpp::R_PPC64_PLT16_LO_DS: + case elfcpp::R_POWERPC_PLTSEQ: +- case elfcpp::R_PPC64_PLTSEQ_NOTOC: + case elfcpp::R_POWERPC_PLTCALL: +- case elfcpp::R_PPC64_PLTCALL_NOTOC: +- case elfcpp::R_PPC64_PLT_PCREL34: +- case elfcpp::R_PPC64_PLT_PCREL34_NOTOC: + ref = Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF; + break; + +- case elfcpp::R_POWERPC_GOT16: +- case elfcpp::R_POWERPC_GOT16_LO: +- case elfcpp::R_POWERPC_GOT16_HI: +- case elfcpp::R_POWERPC_GOT16_HA: + case elfcpp::R_PPC64_GOT16_DS: + case elfcpp::R_PPC64_GOT16_LO_DS: + case elfcpp::R_PPC64_GOT_PCREL34: +@@ -7768,11 +7784,16 @@ Target_powerpc::Scan:: + case elfcpp::R_PPC64_TOC16_HA: + case elfcpp::R_PPC64_TOC16_DS: + case elfcpp::R_PPC64_TOC16_LO_DS: ++ if (size != 64) ++ break; ++ // Fall through. ++ case elfcpp::R_POWERPC_GOT16: ++ case elfcpp::R_POWERPC_GOT16_LO: ++ case elfcpp::R_POWERPC_GOT16_HI: ++ case elfcpp::R_POWERPC_GOT16_HA: + ref = Symbol::RELATIVE_REF; + break; + +- case elfcpp::R_POWERPC_GOT_TPREL16: +- case elfcpp::R_POWERPC_TLS: + case elfcpp::R_PPC64_TLSGD: + case elfcpp::R_PPC64_TLSLD: + case elfcpp::R_PPC64_TPREL34: +@@ -7781,6 +7802,11 @@ Target_powerpc::Scan:: + case elfcpp::R_PPC64_GOT_TLSLD_PCREL34: + case elfcpp::R_PPC64_GOT_TPREL_PCREL34: + case elfcpp::R_PPC64_GOT_DTPREL_PCREL34: ++ if (size != 64) ++ break; ++ // Fall through. ++ case elfcpp::R_POWERPC_GOT_TPREL16: ++ case elfcpp::R_POWERPC_TLS: + ref = Symbol::TLS_REF; + break; + +@@ -10671,10 +10697,8 @@ Target_powerpc::Reloca + bool has_stub_value = false; + bool localentry0 = false; + unsigned int r_sym = elfcpp::elf_r_sym(rela.get_r_info()); +- bool use_plt_offset +- = (gsym != NULL +- ? gsym->use_plt_offset(Scan::get_reference_flags(r_type, target)) +- : object->local_has_plt_offset(r_sym)); ++ bool pltcall_to_direct = false; ++ + if (is_plt16_reloc(r_type) + || r_type == elfcpp::R_PPC64_PLT_PCREL34 + || r_type == elfcpp::R_PPC64_PLT_PCREL34_NOTOC +@@ -10688,21 +10712,18 @@ Target_powerpc::Reloca + // that the decision depends on the PLTCALL reloc, and we don't + // know the address of that instruction when processing others + // in the sequence. So the decision needs to be made in +- // do_relax(). For now, don't optimise inline plt calls. +- if (gsym) +- use_plt_offset = gsym->has_plt_offset(); +- } +- if (use_plt_offset +- && !is_got_reloc(r_type) +- && !is_plt16_reloc(r_type) +- && r_type != elfcpp::R_PPC64_PLT_PCREL34 +- && r_type != elfcpp::R_PPC64_PLT_PCREL34_NOTOC +- && r_type != elfcpp::R_POWERPC_PLTSEQ +- && r_type != elfcpp::R_POWERPC_PLTCALL +- && r_type != elfcpp::R_PPC64_PLTSEQ_NOTOC +- && r_type != elfcpp::R_PPC64_PLTCALL_NOTOC +- && (!psymval->is_ifunc_symbol() +- || Scan::reloc_needs_plt_for_ifunc(target, object, r_type, false))) ++ // do_relax(). ++ pltcall_to_direct = !(gsym != NULL ++ ? gsym->has_plt_offset() ++ : object->local_has_plt_offset(r_sym)); ++ } ++ else if ((gsym != NULL ++ ? gsym->use_plt_offset(Scan::get_reference_flags(r_type, target)) ++ : psymval->is_ifunc_symbol() && object->local_has_plt_offset(r_sym)) ++ && !is_got_reloc(r_type) ++ && (!psymval->is_ifunc_symbol() ++ || Scan::reloc_needs_plt_for_ifunc(target, object, r_type, ++ false))) + { + if (size == 64 + && gsym != NULL +@@ -10796,9 +10817,9 @@ Target_powerpc::Reloca + gold_assert(has_stub_value || !(os->flags() & elfcpp::SHF_ALLOC)); + } + +- if (use_plt_offset && (is_plt16_reloc(r_type) +- || r_type == elfcpp::R_PPC64_PLT_PCREL34 +- || r_type == elfcpp::R_PPC64_PLT_PCREL34_NOTOC)) ++ if (!pltcall_to_direct && (is_plt16_reloc(r_type) ++ || r_type == elfcpp::R_PPC64_PLT_PCREL34 ++ || r_type == elfcpp::R_PPC64_PLT_PCREL34_NOTOC)) + { + const Output_data_plt_powerpc* plt; + if (gsym) +@@ -10826,7 +10847,7 @@ Target_powerpc::Reloca + value -= target->toc_pointer(); + } + } +- else if (!use_plt_offset ++ else if (pltcall_to_direct + && (is_plt16_reloc(r_type) + || r_type == elfcpp::R_POWERPC_PLTSEQ + || r_type == elfcpp::R_PPC64_PLTSEQ_NOTOC)) +@@ -10835,7 +10856,7 @@ Target_powerpc::Reloca + elfcpp::Swap<32, big_endian>::writeval(iview, nop); + r_type = elfcpp::R_POWERPC_NONE; + } +- else if (!use_plt_offset ++ else if (pltcall_to_direct + && (r_type == elfcpp::R_PPC64_PLT_PCREL34 + || r_type == elfcpp::R_PPC64_PLT_PCREL34_NOTOC)) + { +@@ -11316,8 +11337,8 @@ Target_powerpc::Reloca + } + else if (!has_stub_value) + { +- if (!use_plt_offset && (r_type == elfcpp::R_POWERPC_PLTCALL +- || r_type == elfcpp::R_PPC64_PLTCALL_NOTOC)) ++ if (pltcall_to_direct && (r_type == elfcpp::R_POWERPC_PLTCALL ++ || r_type == elfcpp::R_PPC64_PLTCALL_NOTOC)) + { + // PLTCALL without plt entry => convert to direct call + Insn* iview = reinterpret_cast(view); diff --git a/toolchain/binutils/patches/2.39/011-PR29466-APP-NO_APP-with-.linefile.patch b/toolchain/binutils/patches/2.39/011-PR29466-APP-NO_APP-with-.linefile.patch new file mode 100644 index 000000000..f7b581992 --- /dev/null +++ b/toolchain/binutils/patches/2.39/011-PR29466-APP-NO_APP-with-.linefile.patch @@ -0,0 +1,167 @@ +From 9e855cffa1fda44629e7f9b76dfa3e5a51a440e9 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Thu, 11 Aug 2022 09:51:03 +0930 +Subject: [PATCH 011/160] PR29466, APP/NO_APP with .linefile + +Commit 53f2b36a54b9 exposed a bug in sb_scrub_and_add_sb that could +result in losing input. If scrubbing results in expansion past the +holding capacity of do_scrub_chars output buffer, then do_scrub_chars +stashes the extra input for the next call. That call never came +because sb_scrub_and_add_sb wrongly decided it was done. Fix that by +allowing sb_scrub_and_add_sb to see whether there is pending input. +Also allow a little extra space so that in most cases we won't need +to resize the output buffer. + +sb_scrub_and_add_sb also limited output to the size of the input, +rather than the actual output buffer size. Fixing that resulted in a +fail of gas/testsuite/macros/dot with an extra warning: "end of file +not at end of a line; newline inserted". OK, so the macro in dot.s +really does finish without end-of-line. Apparently the macro +expansion code relied on do_scrub_chars returning early. So fix that +too by adding a newline if needed in macro_expand_body. + + PR 29466 + * app.c (do_scrub_pending): New function. + * as.h: Declare it. + * input-scrub.c (input_scrub_include_sb): Add extra space for + two .linefile directives. + * sb.c (sb_scrub_and_add_sb): Take into account pending input. + Allow output to max. + * macro.c (macro_expand_body): Add terminating newline. + * testsuite/config/default.exp (SIZE, SIZEFLAGS): Define. + * testsuite/gas/macros/app5.d, + * testsuite/gas/macros/app5.s: New test. + * testsuite/gas/macros/macros.exp: Run it. + +(cherry picked from commit 4d74aab7aa562fe79d4669cdad0c32610531cbc0) +--- + gas/app.c | 13 +++++++++++++ + gas/as.h | 1 + + gas/input-scrub.c | 6 ++++-- + gas/macro.c | 2 ++ + gas/sb.c | 5 +++-- + gas/testsuite/config/default.exp | 8 ++++++++ + gas/testsuite/gas/macros/app5.d | 6 ++++++ + gas/testsuite/gas/macros/app5.s | 5 +++++ + gas/testsuite/gas/macros/macros.exp | 1 + + 9 files changed, 43 insertions(+), 4 deletions(-) + create mode 100644 gas/testsuite/gas/macros/app5.d + create mode 100644 gas/testsuite/gas/macros/app5.s + +--- a/gas/app.c ++++ b/gas/app.c +@@ -1537,3 +1537,16 @@ do_scrub_chars (size_t (*get) (char *, s + last_char = to[-1]; + return to - tostart; + } ++ ++/* Return amount of pending input. */ ++ ++size_t ++do_scrub_pending (void) ++{ ++ size_t len = 0; ++ if (saved_input) ++ len += saved_input_len; ++ if (state == -1) ++ len += strlen (out_string); ++ return len; ++} +--- a/gas/as.h ++++ b/gas/as.h +@@ -460,6 +460,7 @@ void input_scrub_insert_file (char *); + char * input_scrub_new_file (const char *); + char * input_scrub_next_buffer (char **bufp); + size_t do_scrub_chars (size_t (*get) (char *, size_t), char *, size_t); ++size_t do_scrub_pending (void); + bool scan_for_multibyte_characters (const unsigned char *, const unsigned char *, bool); + int gen_to_words (LITTLENUM_TYPE *, int, long); + int had_err (void); +--- a/gas/input-scrub.c ++++ b/gas/input-scrub.c +@@ -278,9 +278,11 @@ input_scrub_include_sb (sb *from, char * + + next_saved_file = input_scrub_push (position); + +- /* Allocate sufficient space: from->len + optional newline. */ ++ /* Allocate sufficient space: from->len plus optional newline ++ plus two ".linefile " directives, plus a little more for other ++ expansion. */ + newline = from->len >= 1 && from->ptr[0] != '\n'; +- sb_build (&from_sb, from->len + newline); ++ sb_build (&from_sb, from->len + newline + 2 * sizeof (".linefile") + 30); + if (expansion == expanding_repeat && from_sb_expansion >= expanding_macro) + expansion = expanding_nested; + from_sb_expansion = expansion; +--- a/gas/macro.c ++++ b/gas/macro.c +@@ -1056,6 +1056,8 @@ macro_expand_body (sb *in, sb *out, form + loclist = f; + } + ++ if (!err && (out->len == 0 || out->ptr[out->len - 1] != '\n')) ++ sb_add_char (out, '\n'); + return err; + } + +--- a/gas/sb.c ++++ b/gas/sb.c +@@ -119,11 +119,12 @@ sb_scrub_and_add_sb (sb *ptr, sb *s) + So we loop until the input S is consumed. */ + while (1) + { +- size_t copy = s->len - (scrub_position - s->ptr); ++ size_t copy = s->len - (scrub_position - s->ptr) + do_scrub_pending (); + if (copy == 0) + break; + sb_check (ptr, copy); +- ptr->len += do_scrub_chars (scrub_from_sb, ptr->ptr + ptr->len, copy); ++ ptr->len += do_scrub_chars (scrub_from_sb, ptr->ptr + ptr->len, ++ ptr->max - ptr->len); + } + + sb_to_scrub = 0; +--- a/gas/testsuite/config/default.exp ++++ b/gas/testsuite/config/default.exp +@@ -52,6 +52,14 @@ if ![info exists NMFLAGS] then { + set NMFLAGS {} + } + ++if ![info exists SIZE] then { ++ set SIZE [findfile $base_dir/size] ++} ++ ++if ![info exists SIZEFLAGS] then { ++ set SIZEFLAGS "" ++} ++ + if ![info exists OBJCOPY] then { + set OBJCOPY [findfile $base_dir/../../binutils/objcopy] + } +--- /dev/null ++++ b/gas/testsuite/gas/macros/app5.d +@@ -0,0 +1,6 @@ ++#name: APP with linefile ++#xfail: tic30-*-* ++#size: -G ++# pr29466 just check that the test assembles ++ ++#pass +--- /dev/null ++++ b/gas/testsuite/gas/macros/app5.s +@@ -0,0 +1,5 @@ ++#NO_APP ++#APP ++# 5 "foo.c" 1 ++# 0 "" 2 ++#NO_APP +--- a/gas/testsuite/gas/macros/macros.exp ++++ b/gas/testsuite/gas/macros/macros.exp +@@ -70,6 +70,7 @@ run_dump_test app2 + run_dump_test app3 + remote_download host "$srcdir/$subdir/app4b.s" + run_dump_test app4 ++run_dump_test app5 + + run_list_test badarg "" + diff --git a/toolchain/binutils/patches/2.39/039-LoongArch-ld-Fix-relocation-error-of-pcrel.patch b/toolchain/binutils/patches/2.39/039-LoongArch-ld-Fix-relocation-error-of-pcrel.patch new file mode 100644 index 000000000..67e499de6 --- /dev/null +++ b/toolchain/binutils/patches/2.39/039-LoongArch-ld-Fix-relocation-error-of-pcrel.patch @@ -0,0 +1,128 @@ +From 509a2ec6ad3ea7eb3f4cf59538cf636a2126e4c3 Mon Sep 17 00:00:00 2001 +From: liuzhensong +Date: Fri, 2 Sep 2022 16:29:14 +0800 +Subject: [PATCH 039/160] LoongArch:ld: Fix relocation error of pcrel. + + Patch for branch 2.39. + Need to reduce the address of pc when using + reloction R_LARCH_SOP_PUSH_PCREL. + + bfd/ + * elfnn-loongarch.c +--- + bfd/elfnn-loongarch.c | 3 +- + ld/testsuite/ld-loongarch-elf/pcrel-const.d | 14 +++++++ + ld/testsuite/ld-loongarch-elf/pcrel-const.lds | 14 +++++++ + ld/testsuite/ld-loongarch-elf/pcrel-const.s | 12 ++++++ + ld/testsuite/ld-loongarch-elf/pr.exp | 39 +++++++++++++++++++ + 5 files changed, 81 insertions(+), 1 deletion(-) + create mode 100644 ld/testsuite/ld-loongarch-elf/pcrel-const.d + create mode 100644 ld/testsuite/ld-loongarch-elf/pcrel-const.lds + create mode 100644 ld/testsuite/ld-loongarch-elf/pcrel-const.s + create mode 100644 ld/testsuite/ld-loongarch-elf/pr.exp + +--- a/bfd/elfnn-loongarch.c ++++ b/bfd/elfnn-loongarch.c +@@ -2341,9 +2341,10 @@ loongarch_elf_relocate_section (bfd *out + case R_LARCH_SOP_PUSH_PLT_PCREL: + unresolved_reloc = false; + +- if (resolved_to_const) ++ if (!is_undefweak && resolved_to_const) + { + relocation += rel->r_addend; ++ relocation -= pc; + break; + } + else if (is_undefweak) +--- /dev/null ++++ b/ld/testsuite/ld-loongarch-elf/pcrel-const.d +@@ -0,0 +1,14 @@ ++#as: -mla-global-with-pcrel ++#objdump: -Drsz ++ ++.*:[ ]+file format .* ++ ++ ++Disassembly of section .text: ++ ++.* : ++#... ++[ ]+8:[ ]+02c04084[ ]+addi.d[ ]+\$a0,[ ]+\$a0,[ ]+16\(0x10\) ++#... ++0+14 <__sec_end>: ++#pass +--- /dev/null ++++ b/ld/testsuite/ld-loongarch-elf/pcrel-const.lds +@@ -0,0 +1,14 @@ ++ENTRY(foo); ++SECTIONS ++{ ++ .text : { ++ *(.text*) ++ } ++ ++ .data : { ++ __sec_start = .; ++ *(.gzdata) ++ __sec_end = .; ++ } ++} ++PROVIDE(__sec_size = __sec_end); +--- /dev/null ++++ b/ld/testsuite/ld-loongarch-elf/pcrel-const.s +@@ -0,0 +1,12 @@ ++ .text ++ .align 2 ++ .globl foo ++ .type foo, @function ++foo: ++ nop ++ la.global $r4,__sec_size ++ ldptr.w $r4,$r4,0 ++ jr $r1 ++ .size foo, .-foo ++ .data ++ .word 1 +--- /dev/null ++++ b/ld/testsuite/ld-loongarch-elf/pr.exp +@@ -0,0 +1,39 @@ ++# Expect script for LoongArch ELF linker tests ++# Copyright (C) 2022 Free Software Foundation, Inc. ++# ++# This file is part of the GNU Binutils. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++# MA 02110-1301, USA. ++# ++ ++if ![istarget loongarch64-*-*] { ++ return ++} ++ ++set link_tests [list \ ++ [list \ ++ "pcrel const" \ ++ "-T pcrel-const.lds" "" \ ++ "-mla-global-with-pcrel" \ ++ { pcrel-const.s } \ ++ [list \ ++ [list objdump -D pcrel-const.d] \ ++ ] \ ++ "pcrel-const" \ ++ ] \ ++] ++ ++run_ld_link_tests $link_tests diff --git a/toolchain/binutils/patches/2.39/043-Re-PR29466-APP-NO_APP-with-linefile.patch b/toolchain/binutils/patches/2.39/043-Re-PR29466-APP-NO_APP-with-linefile.patch new file mode 100644 index 000000000..1de501a1a --- /dev/null +++ b/toolchain/binutils/patches/2.39/043-Re-PR29466-APP-NO_APP-with-linefile.patch @@ -0,0 +1,27 @@ +From 4233be14a34d754a70b8b6f6fa42d21f35c6e030 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Sat, 10 Sep 2022 07:30:57 +0930 +Subject: [PATCH 043/160] Re: PR29466, APP/NO_APP with linefile + +It looks like I copied the SIZE init across from +binutils/testsuite/config/default.exp without some necessary editing. + + PR 29466 + * testsuite/config/default.exp (SIZE): Adjust relative path. + +(cherry picked from commit 1180f540d5f2f7751b5309bdd6c38d69fcf699e7) +--- + gas/testsuite/config/default.exp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/gas/testsuite/config/default.exp ++++ b/gas/testsuite/config/default.exp +@@ -53,7 +53,7 @@ if ![info exists NMFLAGS] then { + } + + if ![info exists SIZE] then { +- set SIZE [findfile $base_dir/size] ++ set SIZE [findfile $base_dir/../../binutils/size] + } + + if ![info exists SIZEFLAGS] then { diff --git a/toolchain/binutils/patches/2.39/050-PowerPC64-pcrel-got-relocs-against-local-symbols.patch b/toolchain/binutils/patches/2.39/050-PowerPC64-pcrel-got-relocs-against-local-symbols.patch new file mode 100644 index 000000000..5c89f6804 --- /dev/null +++ b/toolchain/binutils/patches/2.39/050-PowerPC64-pcrel-got-relocs-against-local-symbols.patch @@ -0,0 +1,38 @@ +From 4d7bba23a39fba18d6d13a2941a3c232011a7064 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Fri, 16 Sep 2022 18:08:44 +0930 +Subject: [PATCH 050/160] PowerPC64 pcrel got relocs against local symbols + +Not that anyone would want to indirect via the GOT when an address can +be loaded directly with pla, the following: + + pld 3,x@got@pcrel +x: + +leads to "Internal error in md_apply_fix", because the generic parts +of assembler fixup handling convert the fx_pcrel fixup to one without +a symbol. Stop that happening. + + * config/tc-ppc.c (ppc_force_relocation): Add PLT_PCREL34 and + assorted GOT_PCREL34 relocs. + +(cherry picked from commit 49c3ed081fed6b8e2b48fdc48f805f11e4589514) +--- + gas/config/tc-ppc.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/gas/config/tc-ppc.c ++++ b/gas/config/tc-ppc.c +@@ -6676,6 +6676,12 @@ ppc_force_relocation (fixS *fix) + case BFD_RELOC_PPC_BA16_BRNTAKEN: + case BFD_RELOC_24_PLT_PCREL: + case BFD_RELOC_PPC64_TOC: ++ case BFD_RELOC_PPC64_PLT_PCREL34: ++ case BFD_RELOC_PPC64_GOT_PCREL34: ++ case BFD_RELOC_PPC64_GOT_TLSGD_PCREL34: ++ case BFD_RELOC_PPC64_GOT_TLSLD_PCREL34: ++ case BFD_RELOC_PPC64_GOT_TPREL_PCREL34: ++ case BFD_RELOC_PPC64_GOT_DTPREL_PCREL34: + return 1; + case BFD_RELOC_PPC_B26: + case BFD_RELOC_PPC_BA26: diff --git a/toolchain/binutils/patches/2.39/055-Re-PowerPC64-pcrel-got-relocs-against-local-symbols.patch b/toolchain/binutils/patches/2.39/055-Re-PowerPC64-pcrel-got-relocs-against-local-symbols.patch new file mode 100644 index 000000000..19b80c344 --- /dev/null +++ b/toolchain/binutils/patches/2.39/055-Re-PowerPC64-pcrel-got-relocs-against-local-symbols.patch @@ -0,0 +1,94 @@ +From 010db38b54b589ca3e95b498aba2831064970171 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Wed, 21 Sep 2022 09:06:29 +0930 +Subject: [PATCH 055/160] Re: PowerPC64 pcrel got relocs against local symbols + +The last patch wasn't all that shiny. There are rather a lot more +relocations that can hit the assertion in md_apply_fix if the symbol +is local or absolute. Fix them all. + + * config/tc-ppc.c (ppc_force_relocation): Add all relocs that + expect a symbol in md_apply_fix. Remove tls pcrel relocs + already covered in general tls match range. + +(cherry picked from commit 8b168f1a1e09e337d2a970f204a0230c091bbe58) +--- + gas/config/tc-ppc.c | 58 ++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 52 insertions(+), 6 deletions(-) + +--- a/gas/config/tc-ppc.c ++++ b/gas/config/tc-ppc.c +@@ -6666,8 +6666,6 @@ ppc_force_relocation (fixS *fix) + int + ppc_force_relocation (fixS *fix) + { +- /* Branch prediction relocations must force a relocation, as must +- the vtable description relocs. */ + switch (fix->fx_r_type) + { + case BFD_RELOC_PPC_B16_BRTAKEN: +@@ -6676,12 +6674,60 @@ ppc_force_relocation (fixS *fix) + case BFD_RELOC_PPC_BA16_BRNTAKEN: + case BFD_RELOC_24_PLT_PCREL: + case BFD_RELOC_PPC64_TOC: ++ case BFD_RELOC_16_GOTOFF: ++ case BFD_RELOC_LO16_GOTOFF: ++ case BFD_RELOC_HI16_GOTOFF: ++ case BFD_RELOC_HI16_S_GOTOFF: ++ case BFD_RELOC_LO16_PLTOFF: ++ case BFD_RELOC_HI16_PLTOFF: ++ case BFD_RELOC_HI16_S_PLTOFF: ++ case BFD_RELOC_GPREL16: ++ case BFD_RELOC_16_BASEREL: ++ case BFD_RELOC_LO16_BASEREL: ++ case BFD_RELOC_HI16_BASEREL: ++ case BFD_RELOC_HI16_S_BASEREL: ++ case BFD_RELOC_PPC_TOC16: ++ case BFD_RELOC_PPC64_TOC16_LO: ++ case BFD_RELOC_PPC64_TOC16_HI: ++ case BFD_RELOC_PPC64_TOC16_HA: ++ case BFD_RELOC_PPC64_PLTGOT16: ++ case BFD_RELOC_PPC64_PLTGOT16_LO: ++ case BFD_RELOC_PPC64_PLTGOT16_HI: ++ case BFD_RELOC_PPC64_PLTGOT16_HA: ++ case BFD_RELOC_PPC64_GOT16_DS: ++ case BFD_RELOC_PPC64_GOT16_LO_DS: ++ case BFD_RELOC_PPC64_PLT16_LO_DS: ++ case BFD_RELOC_PPC64_SECTOFF_DS: ++ case BFD_RELOC_PPC64_SECTOFF_LO_DS: ++ case BFD_RELOC_PPC64_TOC16_DS: ++ case BFD_RELOC_PPC64_TOC16_LO_DS: ++ case BFD_RELOC_PPC64_PLTGOT16_DS: ++ case BFD_RELOC_PPC64_PLTGOT16_LO_DS: ++ case BFD_RELOC_PPC_EMB_NADDR16: ++ case BFD_RELOC_PPC_EMB_NADDR16_LO: ++ case BFD_RELOC_PPC_EMB_NADDR16_HI: ++ case BFD_RELOC_PPC_EMB_NADDR16_HA: ++ case BFD_RELOC_PPC_EMB_SDAI16: ++ case BFD_RELOC_PPC_EMB_SDA2I16: ++ case BFD_RELOC_PPC_EMB_SDA2REL: ++ case BFD_RELOC_PPC_EMB_SDA21: ++ case BFD_RELOC_PPC_EMB_MRKREF: ++ case BFD_RELOC_PPC_EMB_RELSEC16: ++ case BFD_RELOC_PPC_EMB_RELST_LO: ++ case BFD_RELOC_PPC_EMB_RELST_HI: ++ case BFD_RELOC_PPC_EMB_RELST_HA: ++ case BFD_RELOC_PPC_EMB_BIT_FLD: ++ case BFD_RELOC_PPC_EMB_RELSDA: ++ case BFD_RELOC_PPC_VLE_SDA21: ++ case BFD_RELOC_PPC_VLE_SDA21_LO: ++ case BFD_RELOC_PPC_VLE_SDAREL_LO16A: ++ case BFD_RELOC_PPC_VLE_SDAREL_LO16D: ++ case BFD_RELOC_PPC_VLE_SDAREL_HI16A: ++ case BFD_RELOC_PPC_VLE_SDAREL_HI16D: ++ case BFD_RELOC_PPC_VLE_SDAREL_HA16A: ++ case BFD_RELOC_PPC_VLE_SDAREL_HA16D: + case BFD_RELOC_PPC64_PLT_PCREL34: + case BFD_RELOC_PPC64_GOT_PCREL34: +- case BFD_RELOC_PPC64_GOT_TLSGD_PCREL34: +- case BFD_RELOC_PPC64_GOT_TLSLD_PCREL34: +- case BFD_RELOC_PPC64_GOT_TPREL_PCREL34: +- case BFD_RELOC_PPC64_GOT_DTPREL_PCREL34: + return 1; + case BFD_RELOC_PPC_B26: + case BFD_RELOC_PPC_BA26: diff --git a/toolchain/binutils/patches/2.39/058-elf-Reset-alignment-for-each-PT_LOAD-segment.patch b/toolchain/binutils/patches/2.39/058-elf-Reset-alignment-for-each-PT_LOAD-segment.patch new file mode 100644 index 000000000..aaf7a1b05 --- /dev/null +++ b/toolchain/binutils/patches/2.39/058-elf-Reset-alignment-for-each-PT_LOAD-segment.patch @@ -0,0 +1,89 @@ +From a98316d5cf970cbc99689797d84c2ea832bcdcbb Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Mon, 1 Aug 2022 16:02:39 -0700 +Subject: [PATCH 058/160] elf: Reset alignment for each PT_LOAD segment + +Reset alignment for each PT_LOAD segment to avoid using alignment from +the previous PT_LOAD segment. + +bfd/ + + PR ld/29435 + * elf.c (assign_file_positions_for_load_sections): Reset + alignment for each PT_LOAD segment. + +ld/ + + PR ld/29435 + * testsuite/ld-elf/pr29435.d: New file. + * testsuite/ld-elf/pr29435.s: Likewise. + +(cherry picked from commit 59f214544c50ec7ebbca285ff2b4949f48671690) +--- + bfd/elf.c | 7 ++++--- + ld/testsuite/ld-elf/pr29435.d | 11 +++++++++++ + ld/testsuite/ld-elf/pr29435.s | 6 ++++++ + 3 files changed, 21 insertions(+), 3 deletions(-) + create mode 100644 ld/testsuite/ld-elf/pr29435.d + create mode 100644 ld/testsuite/ld-elf/pr29435.s + +--- a/bfd/elf.c ++++ b/bfd/elf.c +@@ -5438,8 +5438,6 @@ assign_file_positions_for_load_sections + Elf_Internal_Phdr *p; + file_ptr off; /* Octets. */ + bfd_size_type maxpagesize; +- bfd_size_type p_align; +- bool p_align_p = false; + unsigned int alloc, actual; + unsigned int i, j; + struct elf_segment_map **sorted_seg_map; +@@ -5524,7 +5522,6 @@ assign_file_positions_for_load_sections + qsort (sorted_seg_map, alloc, sizeof (*sorted_seg_map), + elf_sort_segments); + +- p_align = bed->p_align; + maxpagesize = 1; + if ((abfd->flags & D_PAGED) != 0) + { +@@ -5559,6 +5556,8 @@ assign_file_positions_for_load_sections + asection **secpp; + bfd_vma off_adjust; /* Octets. */ + bool no_contents; ++ bfd_size_type p_align; ++ bool p_align_p; + + /* An ELF segment (described by Elf_Internal_Phdr) may contain a + number of sections with contents contributing to both p_filesz +@@ -5569,6 +5568,8 @@ assign_file_positions_for_load_sections + p = phdrs + m->idx; + p->p_type = m->p_type; + p->p_flags = m->p_flags; ++ p_align = bed->p_align; ++ p_align_p = false; + + if (m->count == 0) + p->p_vaddr = m->p_vaddr_offset * opb; +--- /dev/null ++++ b/ld/testsuite/ld-elf/pr29435.d +@@ -0,0 +1,11 @@ ++#ld: -shared -z separate-code -z relro ++#xfail: ![check_shared_lib_support] ++#xfail: ![check_relro_support] ++#readelf: -Wl ++ ++#failif ++#... ++ +LOAD +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ .* 0x8000 ++#... ++ +LOAD +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ .* 0x8000 ++#... +--- /dev/null ++++ b/ld/testsuite/ld-elf/pr29435.s +@@ -0,0 +1,6 @@ ++ .text ++ .balign 0x8000 ++ .globl foo ++ .type foo, %function ++foo: ++ .byte 0 diff --git a/toolchain/binutils/patches/2.39/063-PR29542-PowerPC-gold-internal-error-in-get_output_vi.patch b/toolchain/binutils/patches/2.39/063-PR29542-PowerPC-gold-internal-error-in-get_output_vi.patch new file mode 100644 index 000000000..0d66b7750 --- /dev/null +++ b/toolchain/binutils/patches/2.39/063-PR29542-PowerPC-gold-internal-error-in-get_output_vi.patch @@ -0,0 +1,29 @@ +From 041c22e35de06d22566f4c71e4425c3351215e66 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Sun, 25 Sep 2022 12:07:36 +0930 +Subject: [PATCH 063/160] PR29542, PowerPC gold internal error in + get_output_view, + +We were attempting to set a BSS style section contents. + + PR 29542 + * powerpc.cc (Output_data_plt_powerpc::do_write): Don't set .plt, + .iplt or .lplt section contents when position independent. + +(cherry picked from commit c21736aed1d4877e090df60362413669dbdc391d) +--- + gold/powerpc.cc | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/gold/powerpc.cc ++++ b/gold/powerpc.cc +@@ -4338,7 +4338,8 @@ template + void + Output_data_plt_powerpc::do_write(Output_file* of) + { +- if (!this->sym_ents_.empty()) ++ if (!this->sym_ents_.empty() ++ && !parameters->options().output_is_position_independent()) + { + const section_size_type offset = this->offset(); + const section_size_type oview_size diff --git a/toolchain/binutils/patches/2.39/116-arm-Use-DWARF-numbering-convention-for-pseudo-regist.patch b/toolchain/binutils/patches/2.39/116-arm-Use-DWARF-numbering-convention-for-pseudo-regist.patch new file mode 100644 index 000000000..82a015ee2 --- /dev/null +++ b/toolchain/binutils/patches/2.39/116-arm-Use-DWARF-numbering-convention-for-pseudo-regist.patch @@ -0,0 +1,301 @@ +From 88ac930a725b8aac8284a2738f03b843f4343dd0 Mon Sep 17 00:00:00 2001 +From: Victor Do Nascimento +Date: Thu, 17 Nov 2022 14:48:37 +0000 +Subject: [PATCH 116/160] arm: Use DWARF numbering convention for + pseudo-register representation + +The patch, initially submitted to trunk in +https://sourceware.org/pipermail/binutils/2022-July/122092.html ensures correct +support for handling .save directives for mixed-register type lists involving +the ra_auth_code pseudo-register, whereby the support first introduced in 2.39 +(https://sourceware.org/pipermail/binutils/2022-May/120672.html) led to the +generation of unwinder code popping registers in reversed order. + +gas/Changelog: + + * config/tc-arm.c (REG_RA_AUTH_CODE): New. + (parse_dot_save): Likewise. + (parse_reg_list): Remove obsolete code. + (reg_names): Set ra_auth_code to 143. + (s_arm_unwind_save): Handle core and pseudo-register lists via + parse_dot_save. + (s_arm_unwind_save_mixed): Deleted. + (s_arm_unwind_save_pseudo): Handle one register at a time. + * testsuite/gas/arm/unwind-pacbti-m-readelf.d: Fix test. + * testsuite/gas/arm/unwind-pacbti-m.d: Likewise. + +(cherry picked from commit 3a368c4c248f6e9f4bda3a5369befa17a4560293) +--- + gas/config/tc-arm.c | 159 ++++++++++-------- + .../gas/arm/unwind-pacbti-m-readelf.d | 4 +- + gas/testsuite/gas/arm/unwind-pacbti-m.d | 2 +- + 3 files changed, 95 insertions(+), 70 deletions(-) + +--- a/gas/config/tc-arm.c ++++ b/gas/config/tc-arm.c +@@ -742,6 +742,7 @@ const char * const reg_expected_msgs[] = + #define REG_SP 13 + #define REG_LR 14 + #define REG_PC 15 ++#define REG_RA_AUTH_CODE 143 + + /* ARM instructions take 4bytes in the object file, Thumb instructions + take 2: */ +@@ -1943,21 +1944,6 @@ parse_reg_list (char ** strp, enum reg_l + + reg = arm_reg_parse (&str, rt); + +- /* Skip over allowed registers of alternative types in mixed-type +- register lists. */ +- if (reg == FAIL && rt == REG_TYPE_PSEUDO +- && ((reg = arm_reg_parse (&str, REG_TYPE_RN)) != FAIL)) +- { +- cur_reg = reg; +- continue; +- } +- else if (reg == FAIL && rt == REG_TYPE_RN +- && ((reg = arm_reg_parse (&str, REG_TYPE_PSEUDO)) != FAIL)) +- { +- cur_reg = reg; +- continue; +- } +- + if (etype == REGLIST_CLRM) + { + if (reg == REG_SP || reg == REG_PC) +@@ -4139,7 +4125,6 @@ s_arm_unwind_fnstart (int ignored ATTRIB + unwind.sp_restored = 0; + } + +- + /* Parse a handlerdata directive. Creates the exception handling table entry + for the function. */ + +@@ -4297,15 +4282,19 @@ s_arm_unwind_personality (int ignored AT + /* Parse a directive saving pseudo registers. */ + + static void +-s_arm_unwind_save_pseudo (long range) ++s_arm_unwind_save_pseudo (int regno) + { + valueT op; + +- if (range & (1 << 12)) ++ switch (regno) + { ++ case REG_RA_AUTH_CODE: + /* Opcode for restoring RA_AUTH_CODE. */ + op = 0xb4; + add_unwind_opcode (op, 1); ++ break; ++ default: ++ as_bad (_("Unknown register %d encountered\n"), regno); + } + } + +@@ -4375,6 +4364,80 @@ s_arm_unwind_save_core (long range) + } + } + ++/* Implement correct handling of .save lists enabling the split into ++sublists where necessary, while preserving correct sublist ordering. */ ++ ++static void ++parse_dot_save (char **str_p, int prev_reg) ++{ ++ long core_regs = 0; ++ int reg; ++ int in_range = 0; ++ ++ if (**str_p == ',') ++ *str_p += 1; ++ if (**str_p == '}') ++ { ++ *str_p += 1; ++ return; ++ } ++ ++ while ((reg = arm_reg_parse (str_p, REG_TYPE_RN)) != FAIL) ++ { ++ if (!in_range) ++ { ++ if (core_regs & (1 << reg)) ++ as_tsktsk (_("Warning: duplicated register (r%d) in register list"), ++ reg); ++ else if (reg <= prev_reg) ++ as_tsktsk (_("Warning: register list not in ascending order")); ++ ++ core_regs |= (1 << reg); ++ prev_reg = reg; ++ if (skip_past_char(str_p, '-') != FAIL) ++ in_range = 1; ++ else if (skip_past_comma(str_p) == FAIL) ++ first_error (_("bad register list")); ++ } ++ else ++ { ++ int i; ++ if (reg <= prev_reg) ++ first_error (_("bad range in register list")); ++ for (i = prev_reg + 1; i <= reg; i++) ++ { ++ if (core_regs & (1 << i)) ++ as_tsktsk (_("Warning: duplicated register (r%d) in register list"), ++ i); ++ else ++ core_regs |= 1 << i; ++ } ++ in_range = 0; ++ } ++ } ++ if (core_regs) ++ { ++ /* Higher register numbers go in higher memory addresses. When splitting a list, ++ right-most sublist should therefore be .saved first. Use recursion for this. */ ++ parse_dot_save (str_p, reg); ++ /* We're back from recursion, so emit .save insn for sublist. */ ++ s_arm_unwind_save_core (core_regs); ++ return; ++ } ++ /* Handle pseudo-regs, under assumption these are emitted singly. */ ++ else if ((reg = arm_reg_parse (str_p, REG_TYPE_PSEUDO)) != FAIL) ++ { ++ /* Recurse for remainder of input. Note: No assumption is made regarding which ++ register in core register set holds pseudo-register. It's not considered in ++ ordering check beyond ensuring it's not sandwiched between 2 consecutive ++ registers. */ ++ parse_dot_save (str_p, prev_reg + 1); ++ s_arm_unwind_save_pseudo (reg); ++ return; ++ } ++ else ++ as_bad (BAD_SYNTAX); ++} + + /* Parse a directive saving FPA registers. */ + +@@ -4716,39 +4779,13 @@ s_arm_unwind_save_mmxwcg (void) + ignore_rest_of_line (); + } + +-/* Convert range and mask_range into a sequence of s_arm_unwind_core +- and s_arm_unwind_pseudo operations. We assume that mask_range will +- not have consecutive bits set, or that one operation per bit is +- acceptable. */ +- +-static void +-s_arm_unwind_save_mixed (long range, long mask_range) +-{ +- while (mask_range) +- { +- long mask_bit = mask_range & -mask_range; +- long subrange = range & (mask_bit - 1); +- +- if (subrange) +- s_arm_unwind_save_core (subrange); +- +- s_arm_unwind_save_pseudo (mask_bit); +- range &= ~subrange; +- mask_range &= ~mask_bit; +- } +- +- if (range) +- s_arm_unwind_save_core (range); +-} +- + /* Parse an unwind_save directive. + If the argument is non-zero, this is a .vsave directive. */ + + static void + s_arm_unwind_save (int arch_v6) + { +- char *peek, *mask_peek; +- long range, mask_range; ++ char *peek; + struct reg_entry *reg; + bool had_brace = false; + +@@ -4756,7 +4793,7 @@ s_arm_unwind_save (int arch_v6) + as_bad (MISSING_FNSTART); + + /* Figure out what sort of save we have. */ +- peek = mask_peek = input_line_pointer; ++ peek = input_line_pointer; + + if (*peek == '{') + { +@@ -4788,20 +4825,13 @@ s_arm_unwind_save (int arch_v6) + + case REG_TYPE_PSEUDO: + case REG_TYPE_RN: +- mask_range = parse_reg_list (&mask_peek, REGLIST_PSEUDO); +- range = parse_reg_list (&input_line_pointer, REGLIST_RN); +- +- if (range == FAIL || mask_range == FAIL) +- { +- as_bad (_("expected register list")); +- ignore_rest_of_line (); +- return; +- } +- +- demand_empty_rest_of_line (); +- +- s_arm_unwind_save_mixed (range, mask_range); +- return; ++ { ++ if (had_brace) ++ input_line_pointer++; ++ parse_dot_save (&input_line_pointer, -1); ++ demand_empty_rest_of_line (); ++ return; ++ } + + case REG_TYPE_VFD: + if (arch_v6) +@@ -23993,12 +24023,8 @@ static const struct reg_entry reg_names[ + /* XScale accumulator registers. */ + REGNUM(acc,0,XSCALE), REGNUM(ACC,0,XSCALE), + +- /* DWARF ABI defines RA_AUTH_CODE to 143. It also reserves 134-142 for future +- expansion. RA_AUTH_CODE here is given the value 143 % 134 to make it easy +- for tc_arm_regname_to_dw2regnum to translate to DWARF reg number using +- 134 + reg_number should the range 134 to 142 be used for more pseudo regs +- in the future. This also helps fit RA_AUTH_CODE into a bitmask. */ +- REGDEF(ra_auth_code,12,PSEUDO), ++ /* AADWARF32 defines RA_AUTH_CODE to 143. */ ++ REGDEF(ra_auth_code,143,PSEUDO), + }; + #undef REGDEF + #undef REGNUM +@@ -27905,7 +27931,6 @@ create_unwind_entry (int have_data) + return 0; + } + +- + /* Initialize the DWARF-2 unwind information for this procedure. */ + + void +--- a/gas/testsuite/gas/arm/unwind-pacbti-m-readelf.d ++++ b/gas/testsuite/gas/arm/unwind-pacbti-m-readelf.d +@@ -10,11 +10,11 @@ Unwind section '.ARM.exidx' at offset 0x + + 0x0 : @0x0 + Compact model index: 1 +- 0x84 0x00 pop {r14} + 0xb4 pop {ra_auth_code} + 0x84 0x00 pop {r14} +- 0xb4 pop {ra_auth_code} + 0xa3 pop {r4, r5, r6, r7} + 0xb4 pop {ra_auth_code} ++ 0x84 0x00 pop {r14} ++ 0xb4 pop {ra_auth_code} + 0xa8 pop {r4, r14} + 0xb0 finish +--- a/gas/testsuite/gas/arm/unwind-pacbti-m.d ++++ b/gas/testsuite/gas/arm/unwind-pacbti-m.d +@@ -8,4 +8,4 @@ + .*: file format.* + + Contents of section .ARM.extab: +- 0000 (00840281 b40084b4 b0a8b4a3|81028400 b48400b4 a3b4a8b0) 00000000 .* ++ 0000 (84b40281 84b4a300 b0a8b400|8102b484 00a3b484 00b4a8b0) 00000000 .* diff --git a/toolchain/build_version b/toolchain/build_version new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/toolchain/build_version @@ -0,0 +1 @@ +1 diff --git a/toolchain/gcc/Config.in b/toolchain/gcc/Config.in index 69eacaef9..8a31bf0d2 100644 --- a/toolchain/gcc/Config.in +++ b/toolchain/gcc/Config.in @@ -10,12 +10,9 @@ choice config GCC_USE_VERSION_8 bool "gcc 8.x" - config GCC_USE_VERSION_10 - bool "gcc 10.x" - config GCC_USE_VERSION_11 bool "gcc 11.x" - + config GCC_USE_VERSION_12 bool "gcc 12.x" endchoice diff --git a/toolchain/gcc/Config.version b/toolchain/gcc/Config.version index 8bfb17d03..da915851a 100644 --- a/toolchain/gcc/Config.version +++ b/toolchain/gcc/Config.version @@ -3,10 +3,6 @@ config GCC_VERSION_8 default y if mips || mipsel || mips64 || mips64el bool -config GCC_VERSION_10 - default y if GCC_USE_VERSION_10 - bool - config GCC_VERSION_12 default y if GCC_USE_VERSION_12 bool @@ -14,6 +10,5 @@ config GCC_VERSION_12 config GCC_VERSION string default "8.4.0" if GCC_VERSION_8 - default "10.3.0" if GCC_VERSION_10 default "12.2.0" if GCC_VERSION_12 default "11.3.0" diff --git a/toolchain/gcc/common.mk b/toolchain/gcc/common.mk index e7d45bcb6..1a4a849e4 100644 --- a/toolchain/gcc/common.mk +++ b/toolchain/gcc/common.mk @@ -33,10 +33,6 @@ ifeq ($(PKG_VERSION),8.4.0) PKG_HASH:=e30a6e52d10e1f27ed55104ad233c30bd1e99cfb5ff98ab022dc941edd1b2dd4 endif -ifeq ($(PKG_VERSION),10.3.0) - PKG_HASH:=64f404c1a650f27fc33da242e1f2df54952e3963a49e06e73f6940f3223ac344 -endif - ifeq ($(PKG_VERSION),11.3.0) PKG_HASH:=b47cf2818691f5b1e21df2bb38c795fac2cfbd640ede2d0a5e1c89e338a3ac39 endif @@ -113,6 +109,7 @@ GCC_CONFIGURE:= \ $(if $(CONFIG_mips64)$(CONFIG_mips64el),--with-arch=mips64 \ --with-abi=$(call qstrip,$(CONFIG_MIPS64_ABI))) \ $(if $(CONFIG_arc),--with-cpu=$(CONFIG_CPU_TYPE)) \ + $(if $(CONFIG_powerpc64), $(if $(CONFIG_USE_MUSL),--with-abi=elfv2)) \ --with-gmp=$(TOPDIR)/staging_dir/host \ --with-mpfr=$(TOPDIR)/staging_dir/host \ --with-mpc=$(TOPDIR)/staging_dir/host \ diff --git a/toolchain/gcc/patches-10.x/002-case_insensitive.patch b/toolchain/gcc/patches-10.x/002-case_insensitive.patch deleted file mode 100644 index 409497e5a..000000000 --- a/toolchain/gcc/patches-10.x/002-case_insensitive.patch +++ /dev/null @@ -1,24 +0,0 @@ -commit 81cc26c706b2bc8c8c1eb1a322e5c5157900836e -Author: Felix Fietkau -Date: Sun Oct 19 21:45:51 2014 +0000 - - gcc: do not assume that the Mac OS X filesystem is case insensitive - - Signed-off-by: Felix Fietkau - - SVN-Revision: 42973 - ---- a/include/filenames.h -+++ b/include/filenames.h -@@ -44,11 +44,6 @@ extern "C" { - # define IS_DIR_SEPARATOR(c) IS_DOS_DIR_SEPARATOR (c) - # define IS_ABSOLUTE_PATH(f) IS_DOS_ABSOLUTE_PATH (f) - #else /* not DOSish */ --# if defined(__APPLE__) --# ifndef HAVE_CASE_INSENSITIVE_FILE_SYSTEM --# define HAVE_CASE_INSENSITIVE_FILE_SYSTEM 1 --# endif --# endif /* __APPLE__ */ - # define HAS_DRIVE_SPEC(f) (0) - # define IS_DIR_SEPARATOR(c) IS_UNIX_DIR_SEPARATOR (c) - # define IS_ABSOLUTE_PATH(f) IS_UNIX_ABSOLUTE_PATH (f) diff --git a/toolchain/gcc/patches-10.x/010-documentation.patch b/toolchain/gcc/patches-10.x/010-documentation.patch deleted file mode 100644 index 85990e5ac..000000000 --- a/toolchain/gcc/patches-10.x/010-documentation.patch +++ /dev/null @@ -1,35 +0,0 @@ -commit 098bd91f5eae625c7d2ee621e10930fc4434e5e2 -Author: Luka Perkov -Date: Tue Feb 26 16:16:33 2013 +0000 - - gcc: don't build documentation - - This closes #13039. - - Signed-off-by: Luka Perkov - - SVN-Revision: 35807 - ---- a/gcc/Makefile.in -+++ b/gcc/Makefile.in -@@ -3285,18 +3285,10 @@ doc/gcc.info: $(TEXI_GCC_FILES) - doc/gccint.info: $(TEXI_GCCINT_FILES) - doc/cppinternals.info: $(TEXI_CPPINT_FILES) - --doc/%.info: %.texi -- if [ x$(BUILD_INFO) = xinfo ]; then \ -- $(MAKEINFO) $(MAKEINFOFLAGS) -I . -I $(gcc_docdir) \ -- -I $(gcc_docdir)/include -o $@ $<; \ -- fi -+doc/%.info: - - # Duplicate entry to handle renaming of gccinstall.info --doc/gccinstall.info: $(TEXI_GCCINSTALL_FILES) -- if [ x$(BUILD_INFO) = xinfo ]; then \ -- $(MAKEINFO) $(MAKEINFOFLAGS) -I $(gcc_docdir) \ -- -I $(gcc_docdir)/include -o $@ $<; \ -- fi -+doc/gccinstall.info: - - doc/cpp.dvi: $(TEXI_CPP_FILES) - doc/gcc.dvi: $(TEXI_GCC_FILES) diff --git a/toolchain/gcc/patches-10.x/110-Fix-MIPS-PR-84790.patch b/toolchain/gcc/patches-10.x/110-Fix-MIPS-PR-84790.patch deleted file mode 100644 index 82ac013d3..000000000 --- a/toolchain/gcc/patches-10.x/110-Fix-MIPS-PR-84790.patch +++ /dev/null @@ -1,20 +0,0 @@ -Fix https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84790. -MIPS16 functions have a static assembler prologue which clobbers -registers v0 and v1. Add these register clobbers to function call -instructions. - ---- a/gcc/config/mips/mips.c -+++ b/gcc/config/mips/mips.c -@@ -3132,6 +3132,12 @@ mips_emit_call_insn (rtx pattern, rtx or - emit_insn (gen_update_got_version ()); - } - -+ if (TARGET_MIPS16 && TARGET_USE_GOT) -+ { -+ clobber_reg (&CALL_INSN_FUNCTION_USAGE (insn), MIPS16_PIC_TEMP); -+ clobber_reg (&CALL_INSN_FUNCTION_USAGE (insn), MIPS_PROLOGUE_TEMP (word_mode)); -+ } -+ - if (TARGET_MIPS16 - && TARGET_EXPLICIT_RELOCS - && TARGET_CALL_CLOBBERED_GP) diff --git a/toolchain/gcc/patches-10.x/230-musl_libssp.patch b/toolchain/gcc/patches-10.x/230-musl_libssp.patch deleted file mode 100644 index 63f37662f..000000000 --- a/toolchain/gcc/patches-10.x/230-musl_libssp.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/gcc/gcc.c -+++ b/gcc/gcc.c -@@ -875,7 +875,9 @@ proper position among the other output f - #endif - - #ifndef LINK_SSP_SPEC --#ifdef TARGET_LIBC_PROVIDES_SSP -+#if DEFAULT_LIBC == LIBC_MUSL -+#define LINK_SSP_SPEC "-lssp_nonshared" -+#elif defined(TARGET_LIBC_PROVIDES_SSP) - #define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all" \ - "|fstack-protector-strong|fstack-protector-explicit:}" - #else diff --git a/toolchain/gcc/patches-10.x/300-mips_Os_cpu_rtx_cost_model.patch b/toolchain/gcc/patches-10.x/300-mips_Os_cpu_rtx_cost_model.patch deleted file mode 100644 index 8c4a5fce1..000000000 --- a/toolchain/gcc/patches-10.x/300-mips_Os_cpu_rtx_cost_model.patch +++ /dev/null @@ -1,21 +0,0 @@ -commit ecf7671b769fe96f7b5134be442089f8bdba55d2 -Author: Felix Fietkau -Date: Thu Aug 4 20:29:45 2016 +0200 - -gcc: add a patch to generate better code with Os on mips - -Also happens to reduce compressed code size a bit - -Signed-off-by: Felix Fietkau - ---- a/gcc/config/mips/mips.c -+++ b/gcc/config/mips/mips.c -@@ -20041,7 +20041,7 @@ mips_option_override (void) - flag_pcc_struct_return = 0; - - /* Decide which rtx_costs structure to use. */ -- if (optimize_size) -+ if (0 && optimize_size) - mips_cost = &mips_rtx_cost_optimize_size; - else - mips_cost = &mips_rtx_cost_data[mips_tune]; diff --git a/toolchain/gcc/patches-10.x/810-arm-softfloat-libgcc.patch b/toolchain/gcc/patches-10.x/810-arm-softfloat-libgcc.patch deleted file mode 100644 index 5c9d86aea..000000000 --- a/toolchain/gcc/patches-10.x/810-arm-softfloat-libgcc.patch +++ /dev/null @@ -1,33 +0,0 @@ -commit 8570c4be394cff7282f332f97da2ff569a927ddb -Author: Imre Kaloz -Date: Wed Feb 2 20:06:12 2011 +0000 - - fixup arm soft-float symbols - - SVN-Revision: 25325 - ---- a/libgcc/config/arm/t-linux -+++ b/libgcc/config/arm/t-linux -@@ -1,6 +1,10 @@ - LIB1ASMSRC = arm/lib1funcs.S - LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx _clzsi2 _clzdi2 \ -- _ctzsi2 _arm_addsubdf3 _arm_addsubsf3 -+ _ctzsi2 _arm_addsubdf3 _arm_addsubsf3 \ -+ _arm_negdf2 _arm_muldivdf3 _arm_cmpdf2 _arm_unorddf2 \ -+ _arm_fixdfsi _arm_fixunsdfsi _arm_truncdfsf2 \ -+ _arm_negsf2 _arm_muldivsf3 _arm_cmpsf2 _arm_unordsf2 \ -+ _arm_fixsfsi _arm_fixunssfsi - - # Just for these, we omit the frame pointer since it makes such a big - # difference. ---- a/gcc/config/arm/linux-elf.h -+++ b/gcc/config/arm/linux-elf.h -@@ -58,8 +58,6 @@ - %{shared:-lc} \ - %{!shared:%{profile:-lc_p}%{!profile:-lc}}" - --#define LIBGCC_SPEC "%{mfloat-abi=soft*:-lfloat} -lgcc" -- - #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2" - - #define LINUX_TARGET_LINK_SPEC "%{h*} \ diff --git a/toolchain/gcc/patches-10.x/820-libgcc_pic.patch b/toolchain/gcc/patches-10.x/820-libgcc_pic.patch deleted file mode 100644 index ddd6cf873..000000000 --- a/toolchain/gcc/patches-10.x/820-libgcc_pic.patch +++ /dev/null @@ -1,44 +0,0 @@ -commit c96312958c0621e72c9b32da5bc224ffe2161384 -Author: Felix Fietkau -Date: Mon Oct 19 23:26:09 2009 +0000 - - gcc: create a proper libgcc_pic.a static library for relinking (4.3.3+ for now, backport will follow) - - SVN-Revision: 18086 - ---- a/libgcc/Makefile.in -+++ b/libgcc/Makefile.in -@@ -929,11 +929,12 @@ $(libgcov-driver-objects): %$(objext): $ - - # Static libraries. - libgcc.a: $(libgcc-objects) -+libgcc_pic.a: $(libgcc-s-objects) - libgcov.a: $(libgcov-objects) - libunwind.a: $(libunwind-objects) - libgcc_eh.a: $(libgcc-eh-objects) - --libgcc.a libgcov.a libunwind.a libgcc_eh.a: -+libgcc.a libgcov.a libunwind.a libgcc_eh.a libgcc_pic.a: - -rm -f $@ - - objects="$(objects)"; \ -@@ -957,7 +958,7 @@ all: libunwind.a - endif - - ifeq ($(enable_shared),yes) --all: libgcc_eh.a libgcc_s$(SHLIB_EXT) -+all: libgcc_eh.a libgcc_pic.a libgcc_s$(SHLIB_EXT) - ifneq ($(LIBUNWIND),) - all: libunwind$(SHLIB_EXT) - libgcc_s$(SHLIB_EXT): libunwind$(SHLIB_EXT) -@@ -1163,6 +1164,10 @@ install-shared: - chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_eh.a - $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_eh.a - -+ $(INSTALL_DATA) libgcc_pic.a $(mapfile) $(DESTDIR)$(inst_libdir)/ -+ chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_pic.a -+ $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_pic.a -+ - $(subst @multilib_dir@,$(MULTIDIR),$(subst \ - @shlib_base_name@,libgcc_s,$(subst \ - @shlib_slibdir_qual@,$(MULTIOSSUBDIR),$(SHLIB_INSTALL)))) diff --git a/toolchain/gcc/patches-10.x/840-armv4_pass_fix-v4bx_to_ld.patch b/toolchain/gcc/patches-10.x/840-armv4_pass_fix-v4bx_to_ld.patch deleted file mode 100644 index e3cb616c4..000000000 --- a/toolchain/gcc/patches-10.x/840-armv4_pass_fix-v4bx_to_ld.patch +++ /dev/null @@ -1,28 +0,0 @@ -commit 7edc8ca5456d9743dd0075eb3cc5b04f4f24c8cc -Author: Imre Kaloz -Date: Wed Feb 2 19:34:36 2011 +0000 - - add armv4 fixup patches - - SVN-Revision: 25322 - - ---- a/gcc/config/arm/linux-eabi.h -+++ b/gcc/config/arm/linux-eabi.h -@@ -91,10 +91,15 @@ - #define MUSL_DYNAMIC_LINKER \ - "/lib/ld-musl-arm" MUSL_DYNAMIC_LINKER_E "%{mfloat-abi=hard:hf}%{mfdpic:-fdpic}.so.1" - -+/* For armv4 we pass --fix-v4bx to linker to support EABI */ -+#undef TARGET_FIX_V4BX_SPEC -+#define TARGET_FIX_V4BX_SPEC " %{mcpu=arm8|mcpu=arm810|mcpu=strongarm*"\ -+ "|march=armv4|mcpu=fa526|mcpu=fa626:--fix-v4bx}" -+ - /* At this point, bpabi.h will have clobbered LINK_SPEC. We want to - use the GNU/Linux version, not the generic BPABI version. */ - #undef LINK_SPEC --#define LINK_SPEC EABI_LINK_SPEC \ -+#define LINK_SPEC EABI_LINK_SPEC TARGET_FIX_V4BX_SPEC \ - LINUX_OR_ANDROID_LD (LINUX_TARGET_LINK_SPEC, \ - LINUX_TARGET_LINK_SPEC " " ANDROID_LINK_SPEC) - diff --git a/toolchain/gcc/patches-10.x/850-use_shared_libgcc.patch b/toolchain/gcc/patches-10.x/850-use_shared_libgcc.patch deleted file mode 100644 index 8b17f1374..000000000 --- a/toolchain/gcc/patches-10.x/850-use_shared_libgcc.patch +++ /dev/null @@ -1,54 +0,0 @@ -commit dcfc40358b5a3cae7320c17f8d1cebd5ad5540cd -Author: Felix Fietkau -Date: Sun Feb 12 20:25:47 2012 +0000 - - gcc 4.6: port over the missing patch 850-use_shared_libgcc.patch to prevent libgcc crap from leaking into every single binary - - SVN-Revision: 30486 ---- a/gcc/config/arm/linux-eabi.h -+++ b/gcc/config/arm/linux-eabi.h -@@ -132,10 +132,6 @@ - "%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s} " \ - LINUX_OR_ANDROID_LD (GNU_USER_TARGET_ENDFILE_SPEC, ANDROID_ENDFILE_SPEC) - --/* Use the default LIBGCC_SPEC, not the version in linux-elf.h, as we -- do not use -lfloat. */ --#undef LIBGCC_SPEC -- - /* Clear the instruction cache from `beg' to `end'. This is - implemented in lib1funcs.S, so ensure an error if this definition - is used. */ ---- a/gcc/config/linux.h -+++ b/gcc/config/linux.h -@@ -66,6 +66,10 @@ see the files COPYING3 and COPYING.RUNTI - builtin_version ("CRuntime_Musl"); \ - } while (0) - -+#ifndef LIBGCC_SPEC -+#define LIBGCC_SPEC "%{static|static-libgcc:-lgcc}%{!static:%{!static-libgcc:-lgcc_s}}" -+#endif -+ - /* Determine which dynamic linker to use depending on whether GLIBC or - uClibc or Bionic or musl is the default C library and whether - -muclibc or -mglibc or -mbionic or -mmusl has been passed to change ---- a/libgcc/mkmap-symver.awk -+++ b/libgcc/mkmap-symver.awk -@@ -136,5 +136,5 @@ function output(lib) { - else if (inherit[lib]) - printf("} %s;\n", inherit[lib]); - else -- printf ("\n local:\n\t*;\n};\n"); -+ printf ("\n\t*;\n};\n"); - } ---- a/gcc/config/rs6000/linux.h -+++ b/gcc/config/rs6000/linux.h -@@ -62,6 +62,9 @@ - #undef CPP_OS_DEFAULT_SPEC - #define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)" - -+#undef LIBGCC_SPEC -+#define LIBGCC_SPEC "%{!static:%{!static-libgcc:-lgcc_s}} -lgcc" -+ - #undef LINK_SHLIB_SPEC - #define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}} \ - %{static-pie:-static -pie --no-dynamic-linker -z text}" diff --git a/toolchain/gcc/patches-10.x/851-libgcc_no_compat.patch b/toolchain/gcc/patches-10.x/851-libgcc_no_compat.patch deleted file mode 100644 index d710e4071..000000000 --- a/toolchain/gcc/patches-10.x/851-libgcc_no_compat.patch +++ /dev/null @@ -1,22 +0,0 @@ -commit 64661de100da1ec1061ef3e5e400285dce115e6b -Author: Felix Fietkau -Date: Sun May 10 13:16:35 2015 +0000 - - gcc: add some size optimization patches - - Signed-off-by: Felix Fietkau - - SVN-Revision: 45664 - ---- a/libgcc/config/t-libunwind -+++ b/libgcc/config/t-libunwind -@@ -2,8 +2,7 @@ - - HOST_LIBGCC2_CFLAGS += -DUSE_GAS_SYMVER - --LIB2ADDEH = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c \ -- $(srcdir)/unwind-compat.c $(srcdir)/unwind-dw2-fde-compat.c -+LIB2ADDEH = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c - LIB2ADDEHSTATIC = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c - - # Override the default value from t-slibgcc-elf-ver and mention -lunwind diff --git a/toolchain/gcc/patches-10.x/870-ppc_no_crtsavres.patch b/toolchain/gcc/patches-10.x/870-ppc_no_crtsavres.patch deleted file mode 100644 index bc182f0ce..000000000 --- a/toolchain/gcc/patches-10.x/870-ppc_no_crtsavres.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/gcc/config/rs6000/rs6000-logue.c -+++ b/gcc/config/rs6000/rs6000-logue.c -@@ -348,7 +348,7 @@ rs6000_savres_strategy (rs6000_stack_t * - /* Define cutoff for using out-of-line functions to save registers. */ - if (DEFAULT_ABI == ABI_V4 || TARGET_ELF) - { -- if (!optimize_size) -+ if (1) - { - strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS; - strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS; diff --git a/toolchain/gcc/patches-10.x/881-no_tm_section.patch b/toolchain/gcc/patches-10.x/881-no_tm_section.patch deleted file mode 100644 index 2029910fd..000000000 --- a/toolchain/gcc/patches-10.x/881-no_tm_section.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/libgcc/crtstuff.c -+++ b/libgcc/crtstuff.c -@@ -152,7 +152,7 @@ call_ ## FUNC (void) \ - #endif - - #if !defined(USE_TM_CLONE_REGISTRY) && defined(OBJECT_FORMAT_ELF) --# define USE_TM_CLONE_REGISTRY 1 -+# define USE_TM_CLONE_REGISTRY 0 - #elif !defined(USE_TM_CLONE_REGISTRY) - # define USE_TM_CLONE_REGISTRY 0 - #endif diff --git a/toolchain/gcc/patches-10.x/900-bad-mips16-crt.patch b/toolchain/gcc/patches-10.x/900-bad-mips16-crt.patch deleted file mode 100644 index dd6e9dc88..000000000 --- a/toolchain/gcc/patches-10.x/900-bad-mips16-crt.patch +++ /dev/null @@ -1,9 +0,0 @@ ---- a/libgcc/config/mips/t-mips16 -+++ b/libgcc/config/mips/t-mips16 -@@ -43,3 +43,6 @@ SYNC_CFLAGS = -mno-mips16 - - # Version these symbols if building libgcc.so. - SHLIB_MAPFILES += $(srcdir)/config/mips/libgcc-mips16.ver -+ -+CRTSTUFF_T_CFLAGS += -mno-mips16 -+CRTSTUFF_T_CFLAGS_S += -mno-mips16 diff --git a/toolchain/gcc/patches-10.x/910-mbsd_multi.patch b/toolchain/gcc/patches-10.x/910-mbsd_multi.patch deleted file mode 100644 index 3ed623831..000000000 --- a/toolchain/gcc/patches-10.x/910-mbsd_multi.patch +++ /dev/null @@ -1,146 +0,0 @@ -commit 99368862e44740ff4fd33760893f04e14f9dbdf1 -Author: Felix Fietkau -Date: Tue Jul 31 00:52:27 2007 +0000 - - Port the mbsd_multi patch from freewrt, which adds -fhonour-copts. This will emit warnings in packages that don't use our target cflags properly - - SVN-Revision: 8256 - - This patch brings over a feature from MirBSD: - * -fhonour-copts - If this option is not given, it's warned (depending - on environment variables). This is to catch errors - of misbuilt packages which override CFLAGS themselves. - - This patch was authored by Thorsten Glaser - with copyright assignment to the FSF in effect. - ---- a/gcc/c-family/c-opts.c -+++ b/gcc/c-family/c-opts.c -@@ -107,6 +107,9 @@ static dump_flags_t original_dump_flags; - /* Whether any standard preincluded header has been preincluded. */ - static bool done_preinclude; - -+/* Check if a port honours COPTS. */ -+static int honour_copts = 0; -+ - static void handle_OPT_d (const char *); - static void set_std_cxx98 (int); - static void set_std_cxx11 (int); -@@ -455,6 +458,12 @@ c_common_handle_option (size_t scode, co - flag_no_builtin = !value; - break; - -+ case OPT_fhonour_copts: -+ if (c_language == clk_c) { -+ honour_copts++; -+ } -+ break; -+ - case OPT_fconstant_string_class_: - constant_string_class_name = arg; - break; -@@ -1168,6 +1177,47 @@ c_common_init (void) - return false; - } - -+ if (c_language == clk_c) { -+ char *ev = getenv ("GCC_HONOUR_COPTS"); -+ int evv; -+ if (ev == NULL) -+ evv = -1; -+ else if ((*ev == '0') || (*ev == '\0')) -+ evv = 0; -+ else if (*ev == '1') -+ evv = 1; -+ else if (*ev == '2') -+ evv = 2; -+ else if (*ev == 's') -+ evv = -1; -+ else { -+ warning (0, "unknown GCC_HONOUR_COPTS value, assuming 1"); -+ evv = 1; /* maybe depend this on something like MIRBSD_NATIVE? */ -+ } -+ if (evv == 1) { -+ if (honour_copts == 0) { -+ error ("someone does not honour COPTS at all in lenient mode"); -+ return false; -+ } else if (honour_copts != 1) { -+ warning (0, "someone does not honour COPTS correctly, passed %d times", -+ honour_copts); -+ } -+ } else if (evv == 2) { -+ if (honour_copts == 0) { -+ error ("someone does not honour COPTS at all in strict mode"); -+ return false; -+ } else if (honour_copts != 1) { -+ error ("someone does not honour COPTS correctly, passed %d times", -+ honour_copts); -+ return false; -+ } -+ } else if (evv == 0) { -+ if (honour_copts != 1) -+ inform (UNKNOWN_LOCATION, "someone does not honour COPTS correctly, passed %d times", -+ honour_copts); -+ } -+ } -+ - return true; - } - ---- a/gcc/c-family/c.opt -+++ b/gcc/c-family/c.opt -@@ -1590,6 +1590,9 @@ C++ ObjC++ Optimization Alias(fexception - fhonor-std - C++ ObjC++ WarnRemoved - -+fhonour-copts -+C ObjC C++ ObjC++ RejectNegative -+ - fhosted - C ObjC - Assume normal C execution environment. ---- a/gcc/common.opt -+++ b/gcc/common.opt -@@ -1660,6 +1660,9 @@ fguess-branch-probability - Common Report Var(flag_guess_branch_prob) Optimization - Enable guessing of branch probabilities. - -+fhonour-copts -+Common RejectNegative -+ - ; Nonzero means ignore `#ident' directives. 0 means handle them. - ; Generate position-independent code for executables if possible - ; On SVR4 targets, it also controls whether or not to emit a ---- a/gcc/doc/invoke.texi -+++ b/gcc/doc/invoke.texi -@@ -8171,6 +8171,17 @@ This option is only supported for C and - @option{-Wall} and by @option{-Wpedantic}, which can be disabled with - @option{-Wno-pointer-sign}. - -+@item -fhonour-copts -+@opindex fhonour-copts -+If @env{GCC_HONOUR_COPTS} is set to 1, abort if this option is not -+given at least once, and warn if it is given more than once. -+If @env{GCC_HONOUR_COPTS} is set to 2, abort if this option is not -+given exactly once. -+If @env{GCC_HONOUR_COPTS} is set to 0 or unset, warn if this option -+is not given exactly once. -+The warning is quelled if @env{GCC_HONOUR_COPTS} is set to @samp{s}. -+This flag and environment variable only affect the C language. -+ - @item -Wstack-protector - @opindex Wstack-protector - @opindex Wno-stack-protector ---- a/gcc/opts.c -+++ b/gcc/opts.c -@@ -2318,6 +2318,9 @@ common_handle_option (struct gcc_options - /* Currently handled in a prescan. */ - break; - -+ case OPT_fhonour_copts: -+ break; -+ - case OPT_Werror: - dc->warning_as_error_requested = value; - break; diff --git a/toolchain/gcc/patches-10.x/920-specs_nonfatal_getenv.patch b/toolchain/gcc/patches-10.x/920-specs_nonfatal_getenv.patch deleted file mode 100644 index 487b9e47c..000000000 --- a/toolchain/gcc/patches-10.x/920-specs_nonfatal_getenv.patch +++ /dev/null @@ -1,22 +0,0 @@ -Author: Jo-Philipp Wich -Date: Sat Apr 21 03:02:39 2012 +0000 - - gcc: add patch to make the getenv() spec function nonfatal if requested environment variable is unset - - SVN-Revision: 31390 - ---- a/gcc/gcc.c -+++ b/gcc/gcc.c -@@ -9396,8 +9396,10 @@ getenv_spec_function (int argc, const ch - } - - if (!value) -- fatal_error (input_location, -- "environment variable %qs not defined", varname); -+ { -+ warning (input_location, "environment variable %qs not defined", varname); -+ value = ""; -+ } - - /* We have to escape every character of the environment variable so - they are not interpreted as active spec characters. A diff --git a/toolchain/gcc/patches-10.x/930-fix-mips-noexecstack.patch b/toolchain/gcc/patches-10.x/930-fix-mips-noexecstack.patch deleted file mode 100644 index e795acd1d..000000000 --- a/toolchain/gcc/patches-10.x/930-fix-mips-noexecstack.patch +++ /dev/null @@ -1,111 +0,0 @@ -From da45b3fde60095756f5f6030f6012c23a3d34429 Mon Sep 17 00:00:00 2001 -From: Andrew McDonnell -Date: Fri, 3 Oct 2014 19:09:00 +0930 -Subject: Add .note.GNU-stack section - -See http://lists.busybox.net/pipermail/uclibc/2014-October/048671.html -Below copied from https://gcc.gnu.org/ml/gcc-patches/2014-09/msg02430.html - -Re: [Patch, MIPS] Add .note.GNU-stack section - - From: Steve Ellcey - -On Wed, 2014-09-10 at 10:15 -0700, Eric Christopher wrote: -> -> -> On Wed, Sep 10, 2014 at 9:27 AM, wrote: - -> This works except you did not update the assembly files in -> libgcc or glibc. We (Cavium) have the same patch in our tree -> for a few released versions. - -> Mind just checking yours in then Andrew? - -> Thanks! -> -eric - -I talked to Andrew about what files he changed in GCC and created and -tested this new patch. Andrew also mentioned changing some assembly -files in glibc but I don't see any use of '.section .note.GNU-stack' in -any assembly files in glibc (for any platform) so I wasn't planning on -creating a glibc to add them to mips glibc assembly language files. - -OK to check in this patch? - -Steve Ellcey -sellcey@mips.com - - - -2014-09-26 Steve Ellcey ---- - gcc/config/mips/mips.c | 3 +++ - libgcc/config/mips/crti.S | 4 ++++ - libgcc/config/mips/crtn.S | 3 +++ - libgcc/config/mips/mips16.S | 4 ++++ - libgcc/config/mips/vr4120-div.S | 4 ++++ - 5 files changed, 18 insertions(+) - ---- a/gcc/config/mips/mips.c -+++ b/gcc/config/mips/mips.c -@@ -22881,6 +22881,9 @@ mips_asm_file_end (void) - #define TARGET_ASM_FILE_END mips_asm_file_end - - -+#undef TARGET_ASM_FILE_END -+#define TARGET_ASM_FILE_END file_end_indicate_exec_stack -+ - struct gcc_target targetm = TARGET_INITIALIZER; - - #include "gt-mips.h" ---- a/libgcc/config/mips/crti.S -+++ b/libgcc/config/mips/crti.S -@@ -24,6 +24,10 @@ see the files COPYING3 and COPYING.RUNTI - /* An executable stack is *not* required for these functions. */ - #include "gnustack.h" - -+ -+/* An executable stack is *not* required for these functions. */ -+ .section .note.GNU-stack,"",%progbits -+ - /* 4 slots for argument spill area. 1 for cpreturn, 1 for stack. - Return spill offset of 40 and 20. Aligned to 16 bytes for n32. */ - ---- a/libgcc/config/mips/crtn.S -+++ b/libgcc/config/mips/crtn.S -@@ -24,6 +24,9 @@ see the files COPYING3 and COPYING.RUNTI - /* An executable stack is *not* required for these functions. */ - #include "gnustack.h" - -+/* An executable stack is *not* required for these functions. */ -+ .section .note.GNU-stack,"",%progbits -+ - /* 4 slots for argument spill area. 1 for cpreturn, 1 for stack. - Return spill offset of 40 and 20. Aligned to 16 bytes for n32. */ - ---- a/libgcc/config/mips/mips16.S -+++ b/libgcc/config/mips/mips16.S -@@ -51,6 +51,10 @@ see the files COPYING3 and COPYING.RUNTI - values using the soft-float calling convention, but do the actual - operation using the hard floating point instructions. */ - -+/* An executable stack is *not* required for these functions. */ -+ .section .note.GNU-stack,"",%progbits -+ .previous -+ - #if defined _MIPS_SIM && (_MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIO64) - - /* This file contains 32-bit assembly code. */ ---- a/libgcc/config/mips/vr4120-div.S -+++ b/libgcc/config/mips/vr4120-div.S -@@ -29,6 +29,10 @@ see the files COPYING3 and COPYING.RUNTI - -mfix-vr4120. div and ddiv do not give the correct result when one - of the operands is negative. */ - -+/* An executable stack is *not* required for these functions. */ -+ .section .note.GNU-stack,"",%progbits -+ .previous -+ - .set nomips16 - - #define DIV \ diff --git a/toolchain/gcc/patches-10.x/931-libffi-fix-MIPS-softfloat-build-issue.patch b/toolchain/gcc/patches-10.x/931-libffi-fix-MIPS-softfloat-build-issue.patch deleted file mode 100644 index fb4cb1533..000000000 --- a/toolchain/gcc/patches-10.x/931-libffi-fix-MIPS-softfloat-build-issue.patch +++ /dev/null @@ -1,168 +0,0 @@ -From c0c62fa4256f805389f16ebfc4a60cf789129b50 Mon Sep 17 00:00:00 2001 -From: BangLang Huang -Date: Wed, 9 Nov 2016 10:36:49 +0800 -Subject: [PATCH] libffi: fix MIPS softfloat build issue - -Backported from github.com/libffi/libffi#272 - -Signed-off-by: BangLang Huang -Signed-off-by: Yousong Zhou ---- - libffi/src/mips/n32.S | 17 +++++++++++++++++ - libffi/src/mips/o32.S | 17 +++++++++++++++++ - 2 files changed, 34 insertions(+) - ---- a/libffi/src/mips/n32.S -+++ b/libffi/src/mips/n32.S -@@ -107,6 +107,16 @@ loadregs: - - REG_L t6, 3*FFI_SIZEOF_ARG($fp) # load the flags word into t6. - -+#ifdef __mips_soft_float -+ REG_L a0, 0*FFI_SIZEOF_ARG(t9) -+ REG_L a1, 1*FFI_SIZEOF_ARG(t9) -+ REG_L a2, 2*FFI_SIZEOF_ARG(t9) -+ REG_L a3, 3*FFI_SIZEOF_ARG(t9) -+ REG_L a4, 4*FFI_SIZEOF_ARG(t9) -+ REG_L a5, 5*FFI_SIZEOF_ARG(t9) -+ REG_L a6, 6*FFI_SIZEOF_ARG(t9) -+ REG_L a7, 7*FFI_SIZEOF_ARG(t9) -+#else - and t4, t6, ((1< -Date: Fri, 4 May 2018 18:20:53 +0800 -Subject: [PATCH] gotools: fix compilation when making cross compiler - -libgo is "the runtime support library for the Go programming language. -This library is intended for use with the Go frontend." - -gccgo will link target files with libgo.so which depends on libgcc_s.so.1, but -the linker will complain that it cannot find it. That's because shared libgcc -is not present in the install directory yet. libgo.so was made without problem -because gcc will emit -lgcc_s when compiled with -shared option. When gotools -were being made, it was supplied with -static-libgcc thus no link option was -provided. Check LIBGO in gcc/go/gcc-spec.c for how gccgo make a builtin spec -for linking with libgo.so - -- GccgoCrossCompilation, https://github.com/golang/go/wiki/GccgoCrossCompilation -- Cross-building instructions, http://www.eglibc.org/archives/patches/msg00078.html - -When 3-pass GCC compilation is used, shared libgcc runtime libraries will be -available after gcc pass2 completed and will meet the gotools link requirement -at gcc pass3 ---- - gotools/Makefile.am | 4 +++- - gotools/Makefile.in | 4 +++- - 2 files changed, 6 insertions(+), 2 deletions(-) - ---- a/gotools/Makefile.am -+++ b/gotools/Makefile.am -@@ -26,6 +26,7 @@ PWD_COMMAND = $${PWDCMD-pwd} - STAMP = echo timestamp > - - libgodir = ../$(target_noncanonical)/libgo -+libgccdir = ../$(target_noncanonical)/libgcc - LIBGODEP = $(libgodir)/libgo.la - - LIBGOTOOL = $(libgodir)/libgotool.a -@@ -41,7 +42,8 @@ GOCFLAGS = $(CFLAGS_FOR_TARGET) - GOCOMPILE = $(GOCOMPILER) $(GOCFLAGS) - - AM_GOCFLAGS = -I $(libgodir) --AM_LDFLAGS = -L $(libgodir) -L $(libgodir)/.libs -+AM_LDFLAGS = -L $(libgodir) -L $(libgodir)/.libs \ -+ -L $(libgccdir) -L $(libgccdir)/.libs -lgcc_s - GOLINK = $(GOCOMPILER) $(GOCFLAGS) $(AM_GOCFLAGS) $(LDFLAGS) $(AM_LDFLAGS) -o $@ - - libgosrcdir = $(srcdir)/../libgo/go ---- a/gotools/Makefile.in -+++ b/gotools/Makefile.in -@@ -337,6 +337,7 @@ mkinstalldirs = $(SHELL) $(toplevel_srcd - PWD_COMMAND = $${PWDCMD-pwd} - STAMP = echo timestamp > - libgodir = ../$(target_noncanonical)/libgo -+libgccdir = ../$(target_noncanonical)/libgcc - LIBGODEP = $(libgodir)/libgo.la - LIBGOTOOL = $(libgodir)/libgotool.a - @NATIVE_FALSE@GOCOMPILER = $(GOC) -@@ -346,7 +347,8 @@ LIBGOTOOL = $(libgodir)/libgotool.a - GOCFLAGS = $(CFLAGS_FOR_TARGET) - GOCOMPILE = $(GOCOMPILER) $(GOCFLAGS) - AM_GOCFLAGS = -I $(libgodir) --AM_LDFLAGS = -L $(libgodir) -L $(libgodir)/.libs -+AM_LDFLAGS = -L $(libgodir) -L $(libgodir)/.libs \ -+ -L $(libgccdir) -L $(libgccdir)/.libs -lgcc_s - GOLINK = $(GOCOMPILER) $(GOCFLAGS) $(AM_GOCFLAGS) $(LDFLAGS) $(AM_LDFLAGS) -o $@ - libgosrcdir = $(srcdir)/../libgo/go - cmdsrcdir = $(libgosrcdir)/cmd diff --git a/toolchain/gcc/patches-11.x/400-libsanitizer-cherry-pick-9cf13067cb5088626ba7-from-u.patch b/toolchain/gcc/patches-11.x/400-libsanitizer-cherry-pick-9cf13067cb5088626ba7-from-u.patch new file mode 100644 index 000000000..39869b474 --- /dev/null +++ b/toolchain/gcc/patches-11.x/400-libsanitizer-cherry-pick-9cf13067cb5088626ba7-from-u.patch @@ -0,0 +1,39 @@ +From d2356ebb0084a0d80dbfe33040c9afe938c15d19 Mon Sep 17 00:00:00 2001 +From: Martin Liska +Date: Mon, 11 Jul 2022 22:03:14 +0200 +Subject: [PATCH] libsanitizer: cherry-pick 9cf13067cb5088626ba7 from upstream + +9cf13067cb5088626ba7ee1ec4c42ec59c7995a0 [sanitizer] Remove #include to resolve fsconfig_command/mount_attr conflict with glibc 2.36 + +(cherry picked from commit 2701442d0cf6292f6624443c15813d6d1a3562fe) +--- + .../sanitizer_platform_limits_posix.cpp | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp ++++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp +@@ -72,7 +72,9 @@ + #include + #include + #include ++#if SANITIZER_ANDROID + #include ++#endif + #include + #include + #include +@@ -828,10 +830,10 @@ unsigned struct_ElfW_Phdr_sz = sizeof(El + unsigned IOCTL_EVIOCGPROP = IOCTL_NOT_PRESENT; + unsigned IOCTL_EVIOCSKEYCODE_V2 = IOCTL_NOT_PRESENT; + #endif +- unsigned IOCTL_FS_IOC_GETFLAGS = FS_IOC_GETFLAGS; +- unsigned IOCTL_FS_IOC_GETVERSION = FS_IOC_GETVERSION; +- unsigned IOCTL_FS_IOC_SETFLAGS = FS_IOC_SETFLAGS; +- unsigned IOCTL_FS_IOC_SETVERSION = FS_IOC_SETVERSION; ++ unsigned IOCTL_FS_IOC_GETFLAGS = _IOR('f', 1, long); ++ unsigned IOCTL_FS_IOC_GETVERSION = _IOR('v', 1, long); ++ unsigned IOCTL_FS_IOC_SETFLAGS = _IOW('f', 2, long); ++ unsigned IOCTL_FS_IOC_SETVERSION = _IOW('v', 2, long); + unsigned IOCTL_GIO_CMAP = GIO_CMAP; + unsigned IOCTL_GIO_FONT = GIO_FONT; + unsigned IOCTL_GIO_UNIMAP = GIO_UNIMAP; diff --git a/toolchain/glibc/common.mk b/toolchain/glibc/common.mk index 5acb13b5d..314144eea 100644 --- a/toolchain/glibc/common.mk +++ b/toolchain/glibc/common.mk @@ -7,13 +7,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=glibc -PKG_VERSION:=2.35 +PKG_VERSION:=2.36 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) -PKG_SOURCE_VERSION:=813a8d01716d4e099ec57194a93b14fa08b4beca -PKG_MIRROR_HASH:=8c8d92dde334f0e0f9a0949d25b2950db513ce8723c31ae0b0ef64730a00322f +PKG_SOURCE_VERSION:=3aae843e9e9e6a2502e98ff44d2671b20a023f8e +PKG_MIRROR_HASH:=29bdd6ca699f297de500ea457741d0706d57a69836fa7d45e6cc2cc20484cad4 PKG_SOURCE_URL:=https://sourceware.org/git/glibc.git PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz diff --git a/toolchain/glibc/patches/050-Revert-Disallow-use-of-DES-encryption-functions-in-n.patch b/toolchain/glibc/patches/050-Revert-Disallow-use-of-DES-encryption-functions-in-n.patch index 7dfc8a558..c9db70393 100644 --- a/toolchain/glibc/patches/050-Revert-Disallow-use-of-DES-encryption-functions-in-n.patch +++ b/toolchain/glibc/patches/050-Revert-Disallow-use-of-DES-encryption-functions-in-n.patch @@ -82,7 +82,7 @@ provides them. int totfails = 0; int main (int argc, char *argv[]); -@@ -120,13 +104,3 @@ put8 (char *cp) +@@ -119,13 +103,3 @@ put8 (char *cp) printf("%02x", t); } } @@ -627,7 +627,7 @@ provides them. range [FROM - N + 1, FROM - 1]. If N is odd the first byte in FROM --- a/stdlib/stdlib.h +++ b/stdlib/stdlib.h -@@ -971,6 +971,12 @@ extern int getsubopt (char **__restrict +@@ -984,6 +984,12 @@ extern int getsubopt (char **__restrict #endif diff --git a/toolchain/glibc/patches/200-add-dl-search-paths.patch b/toolchain/glibc/patches/200-add-dl-search-paths.patch index fd4af3694..e927d86f2 100644 --- a/toolchain/glibc/patches/200-add-dl-search-paths.patch +++ b/toolchain/glibc/patches/200-add-dl-search-paths.patch @@ -2,7 +2,7 @@ add /usr/lib to default search path for the dynamic linker --- a/Makeconfig +++ b/Makeconfig -@@ -618,6 +618,9 @@ else +@@ -631,6 +631,9 @@ else default-rpath = $(libdir) endif diff --git a/tools/Makefile b/tools/Makefile index 5ba15c641..c7c7d0075 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -21,11 +21,44 @@ ifneq ($(CONFIG_SDK)$(CONFIG_PACKAGE_kmod-b43)$(CONFIG_BRCMSMAC_USE_FW_FROM_WL), BUILD_B43_TOOLS = y endif -tools-y += autoconf autoconf-archive automake bc bison cmake cpio dosfstools -tools-y += e2fsprogs expat fakeroot findutils firmware-utils flex gengetopt -tools-y += libressl libtool lzma m4 make-ext4fs meson missing-macros mkimage -tools-y += mklibs mtd-utils mtools ninja padjffs2 patch-image -tools-y += patchelf pkgconf quilt squashfskit4 sstrip zip zlib zstd +tools-y += autoconf +tools-y += autoconf-archive +tools-y += automake +tools-y += bc +tools-y += bison +tools-y += cmake +tools-y += cpio +tools-y += dosfstools +tools-y += e2fsprogs +tools-y += expat +tools-y += fakeroot +tools-y += findutils +tools-y += firmware-utils +tools-y += flex +tools-y += gengetopt +tools-y += libdeflate +tools-y += libressl +tools-y += libtool +tools-y += lzma +tools-y += m4 +tools-y += make-ext4fs +tools-y += meson +tools-y += missing-macros +tools-y += mkimage +tools-y += mklibs +tools-y += mtd-utils +tools-y += mtools +tools-y += ninja +tools-y += padjffs2 +tools-y += patch-image +tools-y += patchelf +tools-y += pkgconf +tools-y += quilt +tools-y += squashfskit4 +tools-y += sstrip +tools-y += zip +tools-y += zlib +tools-y += zstd tools-$(if $(CONFIG_BUILD_ALL_HOST_TOOLS)$(BUILD_B43_TOOLS),y) += b43-tools tools-$(if $(CONFIG_BUILD_ALL_HOST_TOOLS)$(BUILD_ISL),y) += isl tools-$(if $(CONFIG_BUILD_ALL_HOST_TOOLS)$(BUILD_TOOLCHAIN),y) += gmp mpc mpfr @@ -56,6 +89,7 @@ $(curdir)/genext2fs/compile := $(curdir)/libtool/compile $(curdir)/gengetopt/compile := $(curdir)/libtool/compile $(curdir)/gmp/compile := $(curdir)/libtool/compile $(curdir)/isl/compile := $(curdir)/gmp/compile +$(curdir)/libdeflate/compile := $(curdir)/cmake/compile $(curdir)/libressl/compile := $(curdir)/pkgconf/compile $(curdir)/libtool/compile := $(curdir)/automake/compile $(curdir)/missing-macros/compile $(curdir)/lzma-old/compile := $(curdir)/zlib/compile diff --git a/tools/libdeflate/Makefile b/tools/libdeflate/Makefile new file mode 100644 index 000000000..d30a8ca67 --- /dev/null +++ b/tools/libdeflate/Makefile @@ -0,0 +1,31 @@ +# +# Copyright (C) 2022 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. + +include $(TOPDIR)/rules.mk + +PKG_NAME:=libdeflate +PKG_VERSION:=1.15 +PKG_RELEASE:=1 + +PKG_SOURCE_URL:=https://github.com/ebiggers/libdeflate.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_VERSION:=v$(PKG_VERSION) +PKG_MIRROR_HASH:=122feff4543541b547dc89e832adf262c81911ae1acbccdc591f0353a85b600a + +include $(INCLUDE_DIR)/host-build.mk +include $(INCLUDE_DIR)/cmake.mk + +define Host/Install + $(INSTALL_BIN) $(HOST_BUILD_DIR)/programs/libdeflate-gzip $(STAGING_DIR_HOST)/bin/ + $(LN) libdeflate-gzip $(STAGING_DIR_HOST)/bin/libdeflate-gunzip +endef + +define Host/Clean + rm -f $(STAGING_DIR_HOST)/bin/libdeflate-gzip + rm -f $(STAGING_DIR_HOST)/bin/libdeflate-gunzip +endef + +$(eval $(call HostBuild)) diff --git a/tools/mkimage/Makefile b/tools/mkimage/Makefile index 10fe6eea4..022ac2197 100644 --- a/tools/mkimage/Makefile +++ b/tools/mkimage/Makefile @@ -7,14 +7,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mkimage -PKG_VERSION:=2022.10 +PKG_VERSION:=2023.01 PKG_SOURCE:=u-boot-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:= \ https://mirror.cyberbits.eu/u-boot \ https://ftp.denx.de/pub/u-boot \ ftp://ftp.denx.de/pub/u-boot -PKG_HASH:=50b4482a505bc281ba8470c399a3c26e145e29b23500bc35c50debd7fa46bdf8 +PKG_HASH:=69423bad380f89a0916636e89e6dcbd2e4512d584308d922d1039d1e4331950f HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/u-boot-$(PKG_VERSION) diff --git a/tools/mkimage/patches/020-tools-mtk_image-split-gfh-header-verification-into-a.patch b/tools/mkimage/patches/020-tools-mtk_image-split-gfh-header-verification-into-a.patch deleted file mode 100644 index c8747ae15..000000000 --- a/tools/mkimage/patches/020-tools-mtk_image-split-gfh-header-verification-into-a.patch +++ /dev/null @@ -1,89 +0,0 @@ -From b6bb61fd3818f4a3025fedbe4d15dbeeaef6ee82 Mon Sep 17 00:00:00 2001 -From: Weijie Gao -Date: Tue, 2 Aug 2022 17:21:34 +0800 -Subject: [PATCH 28/31] tools: mtk_image: split gfh header verification into a - new function - -The verification code of gfh header for NAND and non-NAND are identical. -It's better to define a individual function to reduce redundancy. - -Reviewed-by: Simon Glass -Signed-off-by: Weijie Gao ---- - tools/mtk_image.c | 51 +++++++++++++++++++---------------------------- - 1 file changed, 21 insertions(+), 30 deletions(-) - ---- a/tools/mtk_image.c -+++ b/tools/mtk_image.c -@@ -480,6 +480,25 @@ static int mtk_image_vrec_header(struct - return SHA256_SUM_LEN; - } - -+static int mtk_image_verify_gfh(struct gfh_header *gfh, uint32_t type, int print) -+{ -+ if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME)) -+ return -1; -+ -+ if (le32_to_cpu(gfh->file_info.flash_type) != type) -+ return -1; -+ -+ if (print) -+ printf("Load Address: %08x\n", -+ le32_to_cpu(gfh->file_info.load_addr) + -+ le32_to_cpu(gfh->file_info.jump_offset)); -+ -+ if (print) -+ printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM"); -+ -+ return 0; -+} -+ - static int mtk_image_verify_gen_header(const uint8_t *ptr, int print) - { - union gen_boot_header *gbh = (union gen_boot_header *)ptr; -@@ -542,21 +561,7 @@ static int mtk_image_verify_gen_header(c - - gfh = (struct gfh_header *)(ptr + gfh_offset); - -- if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME)) -- return -1; -- -- if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_GEN) -- return -1; -- -- if (print) -- printf("Load Address: %08x\n", -- le32_to_cpu(gfh->file_info.load_addr) + -- le32_to_cpu(gfh->file_info.jump_offset)); -- -- if (print) -- printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM"); -- -- return 0; -+ return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_GEN, print); - } - - static int mtk_image_verify_nand_header(const uint8_t *ptr, int print) -@@ -610,21 +615,7 @@ static int mtk_image_verify_nand_header( - - gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize)); - -- if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME)) -- return -1; -- -- if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_NAND) -- return -1; -- -- if (print) -- printf("Load Address: %08x\n", -- le32_to_cpu(gfh->file_info.load_addr) + -- le32_to_cpu(gfh->file_info.jump_offset)); -- -- if (print) -- printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM"); -- -- return 0; -+ return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_NAND, print); - } - - static uint32_t crc32be_cal(const void *data, size_t length) diff --git a/tools/mkimage/patches/021-tools-mtk_image-split-the-code-of-generating-NAND-he.patch b/tools/mkimage/patches/021-tools-mtk_image-split-the-code-of-generating-NAND-he.patch deleted file mode 100644 index 9a5332f69..000000000 --- a/tools/mkimage/patches/021-tools-mtk_image-split-the-code-of-generating-NAND-he.patch +++ /dev/null @@ -1,821 +0,0 @@ -From 20ebf03eab571b25e9f62b2764ab84932111dcd6 Mon Sep 17 00:00:00 2001 -From: Weijie Gao -Date: Tue, 2 Aug 2022 17:23:57 +0800 -Subject: [PATCH 29/31] tools: mtk_image: split the code of generating NAND - header into a new file - -The predefined NAND headers take too much spaces in the mtk_image.c. -Moving them into a new file can significantly improve the readability of -both mtk_image.c and the new mtk_nand_headers.c. - -This is a preparation for adding more NAND headers. - -Reviewed-by: Simon Glass -Signed-off-by: Weijie Gao ---- - tools/Makefile | 1 + - tools/mtk_image.c | 305 ++++++--------------------------------- - tools/mtk_image.h | 25 ---- - tools/mtk_nand_headers.c | 286 ++++++++++++++++++++++++++++++++++++ - tools/mtk_nand_headers.h | 61 ++++++++ - 5 files changed, 389 insertions(+), 289 deletions(-) - create mode 100644 tools/mtk_nand_headers.c - create mode 100644 tools/mtk_nand_headers.h - ---- a/tools/Makefile -+++ b/tools/Makefile -@@ -147,6 +147,7 @@ dumpimage-mkimage-objs := aisimage.o \ - gpimage.o \ - gpimage-common.o \ - mtk_image.o \ -+ mtk_nand_headers.o \ - $(ECDSA_OBJS-y) \ - $(RSA_OBJS-y) \ - $(AES_OBJS-y) ---- a/tools/mtk_image.c -+++ b/tools/mtk_image.c -@@ -12,216 +12,7 @@ - #include - #include "imagetool.h" - #include "mtk_image.h" -- --/* NAND header for SPI-NAND with 2KB page + 64B spare */ --static const union nand_boot_header snand_hdr_2k_64_data = { -- .data = { -- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, -- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, -- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, -- 0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00, -- 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D, -- 0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7, -- 0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8, -- 0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00 -- } --}; -- --/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */ --static const union nand_boot_header snand_hdr_2k_128_data = { -- .data = { -- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, -- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, -- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, -- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, -- 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13, -- 0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3, -- 0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7, -- 0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00 -- } --}; -- --/* NAND header for SPI-NAND with 4KB page + 256B spare */ --static const union nand_boot_header snand_hdr_4k_256_data = { -- .data = { -- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, -- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, -- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, -- 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00, -- 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3, -- 0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57, -- 0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F, -- 0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00 -- } --}; -- --/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */ --static const union nand_boot_header nand_hdr_1gb_2k_64_data = { -- .data = { -- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, -- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, -- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, -- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, -- 0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12, -- 0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C, -- 0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82, -- 0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00 -- } --}; -- --/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */ --static const union nand_boot_header nand_hdr_2gb_2k_64_data = { -- .data = { -- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, -- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, -- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, -- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, -- 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D, -- 0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1, -- 0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95, -- 0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00 -- } --}; -- --/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */ --static const union nand_boot_header nand_hdr_4gb_2k_64_data = { -- .data = { -- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, -- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, -- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, -- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, -- 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32, -- 0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B, -- 0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87, -- 0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00 -- } --}; -- --/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */ --static const union nand_boot_header nand_hdr_2gb_2k_128_data = { -- .data = { -- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, -- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, -- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, -- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, -- 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A, -- 0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC, -- 0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0, -- 0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00 -- } --}; -- --/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */ --static const union nand_boot_header nand_hdr_4gb_2k_128_data = { -- .data = { -- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, -- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, -- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, -- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, -- 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -- 0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45, -- 0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46, -- 0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2, -- 0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00 -- } --}; -- --static const struct nand_header_type { -- const char *name; -- const union nand_boot_header *data; --} nand_headers[] = { -- { -- .name = "2k+64", -- .data = &snand_hdr_2k_64_data -- }, { -- .name = "2k+120", -- .data = &snand_hdr_2k_128_data -- }, { -- .name = "2k+128", -- .data = &snand_hdr_2k_128_data -- }, { -- .name = "4k+256", -- .data = &snand_hdr_4k_256_data -- }, { -- .name = "1g:2k+64", -- .data = &nand_hdr_1gb_2k_64_data -- }, { -- .name = "2g:2k+64", -- .data = &nand_hdr_2gb_2k_64_data -- }, { -- .name = "4g:2k+64", -- .data = &nand_hdr_4gb_2k_64_data -- }, { -- .name = "2g:2k+128", -- .data = &nand_hdr_2gb_2k_128_data -- }, { -- .name = "4g:2k+128", -- .data = &nand_hdr_4gb_2k_128_data -- } --}; -+#include "mtk_nand_headers.h" - - static const struct brom_img_type { - const char *name; -@@ -264,6 +55,7 @@ static uint32_t crc32tbl[256]; - - /* NAND header selected by user */ - static const union nand_boot_header *hdr_nand; -+static uint32_t hdr_nand_size; - - /* GFH header + 2 * 4KB pages of NAND */ - static char hdr_tmp[sizeof(struct gfh_header) + 0x2000]; -@@ -402,12 +194,7 @@ static int mtk_brom_parse_imagename(cons - } - - /* parse nand header type */ -- for (i = 0; i < ARRAY_SIZE(nand_headers); i++) { -- if (!strcmp(nand_headers[i].name, nandinfo)) { -- hdr_nand = nand_headers[i].data; -- break; -- } -- } -+ hdr_nand = mtk_nand_header_find(nandinfo); - - /* parse device header offset */ - if (hdr_offs && hdr_offs[0]) -@@ -432,6 +219,9 @@ static int mtk_brom_parse_imagename(cons - return -EINVAL; - } - -+ if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) -+ hdr_nand_size = mtk_nand_header_size(hdr_nand); -+ - return 0; - } - -@@ -468,7 +258,7 @@ static int mtk_image_vrec_header(struct - } - - if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) -- tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize); -+ tparams->header_size = hdr_nand_size; - else - tparams->header_size = sizeof(struct gen_device_header); - -@@ -566,16 +356,17 @@ static int mtk_image_verify_gen_header(c - - static int mtk_image_verify_nand_header(const uint8_t *ptr, int print) - { -- union nand_boot_header *nh = (union nand_boot_header *)ptr; - struct brom_layout_header *bh; -+ struct nand_header_info info; - struct gfh_header *gfh; - const char *bootmedia; -+ int ret; - -- if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) || -- strcmp(nh->id, NAND_BOOT_ID)) -- return -1; -+ ret = mtk_nand_header_info(ptr, &info); -+ if (ret < 0) -+ return ret; - -- bh = (struct brom_layout_header *)(ptr + le16_to_cpu(nh->pagesize)); -+ bh = (struct brom_layout_header *)(ptr + info.page_size); - - if (strcmp(bh->name, BRLYT_NAME)) - return -1; -@@ -586,34 +377,23 @@ static int mtk_image_verify_nand_header( - if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) - bootmedia = "Parallel NAND"; - else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND) -- bootmedia = "Serial NAND"; -+ bootmedia = "Serial NAND (SNFI/AP)"; - else - return -1; - } - - if (print) { -- printf("Boot Media: %s\n", bootmedia); -- -- if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) { -- uint64_t capacity = -- (uint64_t)le16_to_cpu(nh->numblocks) * -- (uint64_t)le16_to_cpu(nh->pages_of_block) * -- (uint64_t)le16_to_cpu(nh->pagesize) * 8; -- printf("Capacity: %dGb\n", -- (uint32_t)(capacity >> 30)); -- } -+ printf("Boot Media: %s\n", bootmedia); - -- if (le16_to_cpu(nh->pagesize) >= 1024) -- printf("Page Size: %dKB\n", -- le16_to_cpu(nh->pagesize) >> 10); -+ if (info.page_size >= 1024) -+ printf("Page Size: %dKB\n", info.page_size >> 10); - else -- printf("Page Size: %dB\n", -- le16_to_cpu(nh->pagesize)); -+ printf("Page Size: %dB\n", info.page_size); - -- printf("Spare Size: %dB\n", le16_to_cpu(nh->oobsize)); -+ printf("Spare Size: %dB\n", info.spare_size); - } - -- gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize)); -+ gfh = (struct gfh_header *)(ptr + info.gfh_offset); - - return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_NAND, print); - } -@@ -713,7 +493,7 @@ static int mtk_image_verify_header(unsig - if (image_get_magic(hdr) == IH_MAGIC) - return mtk_image_verify_mt7621_header(ptr, 0); - -- if (!strcmp((char *)ptr, NAND_BOOT_NAME)) -+ if (is_mtk_nand_header(ptr)) - return mtk_image_verify_nand_header(ptr, 0); - else - return mtk_image_verify_gen_header(ptr, 0); -@@ -739,7 +519,7 @@ static void mtk_image_print_header(const - return; - } - -- if (!strcmp((char *)ptr, NAND_BOOT_NAME)) -+ if (is_mtk_nand_header(ptr)) - mtk_image_verify_nand_header(ptr, 1); - else - mtk_image_verify_gen_header(ptr, 1); -@@ -870,36 +650,33 @@ static void mtk_image_set_gen_header(voi - static void mtk_image_set_nand_header(void *ptr, off_t filesize, - uint32_t loadaddr) - { -- union nand_boot_header *nh = (union nand_boot_header *)ptr; - struct brom_layout_header *brlyt; - struct gfh_header *gfh; -- uint32_t payload_pages; -- int i; -+ uint32_t payload_pages, nand_page_size; - -- /* NAND device header, repeat 4 times */ -- for (i = 0; i < 4; i++) -- memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header)); -+ /* NAND header */ -+ nand_page_size = mtk_nand_header_put(hdr_nand, ptr); - -- /* BRLYT header */ -- payload_pages = (filesize + le16_to_cpu(hdr_nand->pagesize) - 1) / -- le16_to_cpu(hdr_nand->pagesize); -- brlyt = (struct brom_layout_header *) -- (ptr + le16_to_cpu(hdr_nand->pagesize)); -- put_brom_layout_header(brlyt, hdr_media); -- brlyt->header_size = cpu_to_le32(2); -- brlyt->total_size = cpu_to_le32(payload_pages); -- brlyt->header_size_2 = brlyt->header_size; -- brlyt->total_size_2 = brlyt->total_size; -- brlyt->unused = cpu_to_le32(1); -+ if (nand_page_size) { -+ /* BRLYT header */ -+ payload_pages = (filesize + nand_page_size - 1) / -+ nand_page_size; -+ brlyt = (struct brom_layout_header *)(ptr + nand_page_size); -+ put_brom_layout_header(brlyt, hdr_media); -+ brlyt->header_size = cpu_to_le32(2); -+ brlyt->total_size = cpu_to_le32(payload_pages); -+ brlyt->header_size_2 = brlyt->header_size; -+ brlyt->total_size_2 = brlyt->total_size; -+ brlyt->unused = cpu_to_le32(1); -+ } - - /* GFH header */ -- gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(hdr_nand->pagesize)); -- put_ghf_header(gfh, filesize, 2 * le16_to_cpu(hdr_nand->pagesize), -- loadaddr, GFH_FLASH_TYPE_NAND); -+ gfh = (struct gfh_header *)(ptr + hdr_nand_size); -+ put_ghf_header(gfh, filesize, hdr_nand_size, loadaddr, -+ GFH_FLASH_TYPE_NAND); - - /* Generate SHA256 hash */ -- put_hash((uint8_t *)gfh, -- filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN); -+ put_hash((uint8_t *)gfh, filesize - hdr_nand_size - SHA256_SUM_LEN); - } - - static void mtk_image_set_mt7621_header(void *ptr, off_t filesize, ---- a/tools/mtk_image.h -+++ b/tools/mtk_image.h -@@ -26,31 +26,6 @@ union gen_boot_header { - #define SF_BOOT_NAME "SF_BOOT" - #define SDMMC_BOOT_NAME "SDMMC_BOOT" - --/* Header for NAND */ --union nand_boot_header { -- struct { -- char name[12]; -- char version[4]; -- char id[8]; -- uint16_t ioif; -- uint16_t pagesize; -- uint16_t addrcycles; -- uint16_t oobsize; -- uint16_t pages_of_block; -- uint16_t numblocks; -- uint16_t writesize_shift; -- uint16_t erasesize_shift; -- uint8_t dummy[60]; -- uint8_t ecc_parity[28]; -- }; -- -- uint8_t data[0x80]; --}; -- --#define NAND_BOOT_NAME "BOOTLOADER!" --#define NAND_BOOT_VERSION "V006" --#define NAND_BOOT_ID "NFIINFO" -- - /* BootROM layout header */ - struct brom_layout_header { - char name[8]; ---- /dev/null -+++ b/tools/mtk_nand_headers.c -@@ -0,0 +1,286 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * MediaTek BootROM NAND header definitions -+ * -+ * Copyright (C) 2022 MediaTek Inc. -+ * Author: Weijie Gao -+ */ -+ -+#include -+#include -+#include "imagetool.h" -+#include "mtk_image.h" -+#include "mtk_nand_headers.h" -+ -+/* NAND header for SPI-NAND with 2KB page + 64B spare */ -+static const union nand_boot_header snand_hdr_2k_64_data = { -+ .data = { -+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, -+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, -+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, -+ 0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00, -+ 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D, -+ 0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7, -+ 0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8, -+ 0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00 -+ } -+}; -+ -+/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */ -+static const union nand_boot_header snand_hdr_2k_128_data = { -+ .data = { -+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, -+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, -+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, -+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, -+ 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13, -+ 0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3, -+ 0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7, -+ 0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00 -+ } -+}; -+ -+/* NAND header for SPI-NAND with 4KB page + 256B spare */ -+static const union nand_boot_header snand_hdr_4k_256_data = { -+ .data = { -+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, -+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, -+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, -+ 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00, -+ 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3, -+ 0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57, -+ 0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F, -+ 0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00 -+ } -+}; -+ -+/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */ -+static const union nand_boot_header nand_hdr_1gb_2k_64_data = { -+ .data = { -+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, -+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, -+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, -+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, -+ 0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12, -+ 0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C, -+ 0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82, -+ 0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00 -+ } -+}; -+ -+/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */ -+static const union nand_boot_header nand_hdr_2gb_2k_64_data = { -+ .data = { -+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, -+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, -+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, -+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, -+ 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D, -+ 0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1, -+ 0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95, -+ 0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00 -+ } -+}; -+ -+/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */ -+static const union nand_boot_header nand_hdr_4gb_2k_64_data = { -+ .data = { -+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, -+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, -+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, -+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, -+ 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32, -+ 0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B, -+ 0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87, -+ 0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00 -+ } -+}; -+ -+/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */ -+static const union nand_boot_header nand_hdr_2gb_2k_128_data = { -+ .data = { -+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, -+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, -+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, -+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, -+ 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A, -+ 0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC, -+ 0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0, -+ 0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00 -+ } -+}; -+ -+/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */ -+static const union nand_boot_header nand_hdr_4gb_2k_128_data = { -+ .data = { -+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, -+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, -+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, -+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, -+ 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45, -+ 0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46, -+ 0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2, -+ 0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00 -+ } -+}; -+ -+static const struct nand_header_type { -+ const char *name; -+ const union nand_boot_header *data; -+} nand_headers[] = { -+ { -+ .name = "2k+64", -+ .data = &snand_hdr_2k_64_data -+ }, { -+ .name = "2k+120", -+ .data = &snand_hdr_2k_128_data -+ }, { -+ .name = "2k+128", -+ .data = &snand_hdr_2k_128_data -+ }, { -+ .name = "4k+256", -+ .data = &snand_hdr_4k_256_data -+ }, { -+ .name = "1g:2k+64", -+ .data = &nand_hdr_1gb_2k_64_data -+ }, { -+ .name = "2g:2k+64", -+ .data = &nand_hdr_2gb_2k_64_data -+ }, { -+ .name = "4g:2k+64", -+ .data = &nand_hdr_4gb_2k_64_data -+ }, { -+ .name = "2g:2k+128", -+ .data = &nand_hdr_2gb_2k_128_data -+ }, { -+ .name = "4g:2k+128", -+ .data = &nand_hdr_4gb_2k_128_data -+ } -+}; -+ -+const union nand_boot_header *mtk_nand_header_find(const char *name) -+{ -+ uint32_t i; -+ -+ for (i = 0; i < ARRAY_SIZE(nand_headers); i++) { -+ if (!strcmp(nand_headers[i].name, name)) -+ return nand_headers[i].data; -+ } -+ -+ return NULL; -+} -+ -+uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand) -+{ -+ return 2 * le16_to_cpu(hdr_nand->pagesize); -+} -+ -+static int mtk_nand_header_ap_info(const void *ptr, -+ struct nand_header_info *info) -+{ -+ union nand_boot_header *nh = (union nand_boot_header *)ptr; -+ -+ if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) || -+ strcmp(nh->id, NAND_BOOT_ID)) -+ return -1; -+ -+ info->page_size = le16_to_cpu(nh->pagesize); -+ info->spare_size = le16_to_cpu(nh->oobsize); -+ info->gfh_offset = 2 * info->page_size; -+ -+ return 0; -+} -+ -+int mtk_nand_header_info(const void *ptr, struct nand_header_info *info) -+{ -+ if (!strcmp((char *)ptr, NAND_BOOT_NAME)) -+ return mtk_nand_header_ap_info(ptr, info); -+ -+ return -1; -+} -+ -+bool is_mtk_nand_header(const void *ptr) -+{ -+ struct nand_header_info info; -+ -+ if (mtk_nand_header_info(ptr, &info) >= 0) -+ return true; -+ -+ return false; -+} -+ -+uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void *ptr) -+{ -+ union nand_boot_header *nh = (union nand_boot_header *)ptr; -+ int i; -+ -+ /* NAND device header, repeat 4 times */ -+ for (i = 0; i < 4; i++) -+ memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header)); -+ -+ return le16_to_cpu(hdr_nand->pagesize); -+} ---- /dev/null -+++ b/tools/mtk_nand_headers.h -@@ -0,0 +1,61 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ -+/* -+ * MediaTek BootROM NAND header definitions -+ * -+ * Copyright (C) 2022 MediaTek Inc. -+ * Author: Weijie Gao -+ */ -+ -+#ifndef _MTK_NAND_HEADERS_H -+#define _MTK_NAND_HEADERS_H -+ -+#include -+#include -+ -+struct nand_header_info { -+ uint32_t page_size; -+ uint32_t spare_size; -+ uint32_t gfh_offset; -+}; -+ -+/* AP BROM Header for NAND */ -+union nand_boot_header { -+ struct { -+ char name[12]; -+ char version[4]; -+ char id[8]; -+ uint16_t ioif; /* I/O interface */ -+ uint16_t pagesize; /* NAND page size */ -+ uint16_t addrcycles; /* Address cycles */ -+ uint16_t oobsize; /* NAND page spare size */ -+ uint16_t pages_of_block; /* Pages of one block */ -+ uint16_t numblocks; /* Total blocks of NAND chip */ -+ uint16_t writesize_shift; -+ uint16_t erasesize_shift; -+ uint8_t dummy[60]; -+ uint8_t ecc_parity[28]; /* ECC parity of this header */ -+ }; -+ -+ uint8_t data[0x80]; -+}; -+ -+#define NAND_BOOT_NAME "BOOTLOADER!" -+#define NAND_BOOT_VERSION "V006" -+#define NAND_BOOT_ID "NFIINFO" -+ -+/* Find nand header data by name */ -+const union nand_boot_header *mtk_nand_header_find(const char *name); -+ -+/* Device header size using this nand header */ -+uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand); -+ -+/* Get nand info from nand header (page size, spare size, ...) */ -+int mtk_nand_header_info(const void *ptr, struct nand_header_info *info); -+ -+/* Whether given header data is valid */ -+bool is_mtk_nand_header(const void *ptr); -+ -+/* Generate Device header using give nand header */ -+uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void *ptr); -+ -+#endif /* _MTK_NAND_HEADERS_H */ diff --git a/tools/mkimage/patches/022-tools-mtk_image-add-support-for-nand-headers-used-by.patch b/tools/mkimage/patches/022-tools-mtk_image-add-support-for-nand-headers-used-by.patch deleted file mode 100644 index 0ce095998..000000000 --- a/tools/mkimage/patches/022-tools-mtk_image-add-support-for-nand-headers-used-by.patch +++ /dev/null @@ -1,702 +0,0 @@ -From fbf296f9ed5daab70020686e9ba072efe663bbab Mon Sep 17 00:00:00 2001 -From: Weijie Gao -Date: Wed, 3 Aug 2022 11:14:36 +0800 -Subject: [PATCH 30/31] tools: mtk_image: add support for nand headers used by - newer chips - -This patch adds more nand headers in two new types: -1. HSM header, used for spi-nand thru SNFI interface -2. SPIM header, used for spi-nand thru spi-mem interface - -The original nand header is renamed to AP header. - -Signed-off-by: Weijie Gao ---- - tools/mtk_image.c | 23 ++- - tools/mtk_nand_headers.c | 422 +++++++++++++++++++++++++++++++++++++-- - tools/mtk_nand_headers.h | 110 +++++++++- - 3 files changed, 525 insertions(+), 30 deletions(-) - ---- a/tools/mtk_image.c -+++ b/tools/mtk_image.c -@@ -33,6 +33,9 @@ static const struct brom_img_type { - }, { - .name = "snand", - .type = BRLYT_TYPE_SNAND -+ }, { -+ .name = "spim-nand", -+ .type = BRLYT_TYPE_SNAND - } - }; - -@@ -54,7 +57,7 @@ static char lk_name[32] = "U-Boot"; - static uint32_t crc32tbl[256]; - - /* NAND header selected by user */ --static const union nand_boot_header *hdr_nand; -+static const struct nand_header_type *hdr_nand; - static uint32_t hdr_nand_size; - - /* GFH header + 2 * 4KB pages of NAND */ -@@ -366,20 +369,26 @@ static int mtk_image_verify_nand_header( - if (ret < 0) - return ret; - -- bh = (struct brom_layout_header *)(ptr + info.page_size); -+ if (!ret) { -+ bh = (struct brom_layout_header *)(ptr + info.page_size); - -- if (strcmp(bh->name, BRLYT_NAME)) -- return -1; -+ if (strcmp(bh->name, BRLYT_NAME)) -+ return -1; -+ -+ if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) -+ return -1; - -- if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) { -- return -1; -- } else { - if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) - bootmedia = "Parallel NAND"; - else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND) - bootmedia = "Serial NAND (SNFI/AP)"; - else - return -1; -+ } else { -+ if (info.snfi) -+ bootmedia = "Serial NAND (SNFI/HSM)"; -+ else -+ bootmedia = "Serial NAND (SPIM)"; - } - - if (print) { ---- a/tools/mtk_nand_headers.c -+++ b/tools/mtk_nand_headers.c -@@ -188,55 +188,346 @@ static const union nand_boot_header nand - } - }; - --static const struct nand_header_type { -+/* HSM BROM NAND header for SPI NAND with 2KB page + 64B spare */ -+static const union hsm_nand_boot_header hsm_nand_hdr_2k_64_data = { -+ .data = { -+ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, -+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, -+ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, -+ 0xFF, 0x00, 0x00, 0x00, 0x21, 0xD2, 0xEE, 0xF6, -+ 0xAE, 0xDD, 0x5E, 0xC2, 0x82, 0x8E, 0x9A, 0x62, -+ 0x09, 0x8E, 0x80, 0xE2, 0x37, 0x0D, 0xC9, 0xFA, -+ 0xA9, 0xDD, 0xFC, 0x92, 0x34, 0x2A, 0xED, 0x51, -+ 0xA4, 0x1B, 0xF7, 0x63, 0xCC, 0x5A, 0xC7, 0xFB, -+ 0xED, 0x21, 0x02, 0x23, 0x51, 0x31 -+ } -+}; -+ -+/* HSM BROM NAND header for SPI NAND with 2KB page + 128B spare */ -+static const union hsm_nand_boot_header hsm_nand_hdr_2k_128_data = { -+ .data = { -+ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, -+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, -+ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, -+ 0xFF, 0x00, 0x00, 0x00, 0x71, 0x7f, 0x71, 0xAC, -+ 0x42, 0xD0, 0x5B, 0xD2, 0x12, 0x81, 0x15, 0x0A, -+ 0x0C, 0xD4, 0xF6, 0x32, 0x1E, 0x63, 0xE7, 0x81, -+ 0x8A, 0x7F, 0xDE, 0xF9, 0x4B, 0x91, 0xEC, 0xC2, -+ 0x70, 0x00, 0x7F, 0x57, 0xAF, 0xDC, 0xE4, 0x24, -+ 0x57, 0x09, 0xBC, 0xC5, 0x35, 0xDC -+ } -+}; -+ -+/* HSM BROM NAND header for SPI NAND with 4KB page + 256B spare */ -+static const union hsm_nand_boot_header hsm_nand_hdr_4k_256_data = { -+ .data = { -+ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, -+ 0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, -+ 0xFF, 0x00, 0x00, 0x00, 0x62, 0x04, 0xD6, 0x1F, -+ 0x2B, 0x57, 0x7A, 0x2D, 0xFE, 0xBB, 0x4A, 0x50, -+ 0xEC, 0xF8, 0x70, 0x1A, 0x44, 0x15, 0xF6, 0xA2, -+ 0x8E, 0xB0, 0xFD, 0xFA, 0xDC, 0xAA, 0x5A, 0x4E, -+ 0xCB, 0x8E, 0xC9, 0x72, 0x08, 0xDC, 0x20, 0xB9, -+ 0x98, 0xC8, 0x82, 0xD8, 0xBE, 0x44 -+ } -+}; -+ -+/* HSM2.0 BROM NAND header for SPI NAND with 2KB page + 64B spare */ -+static const union hsm20_nand_boot_header hsm20_nand_hdr_2k_64_data = { -+ .data = { -+ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, -+ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, -+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, -+ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, -+ 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x5F, 0x4B, 0xB2, 0x5B, 0x8B, 0x1C, 0x35, 0xDA, -+ 0x83, 0xE6, 0x6C, 0xC3, 0xFB, 0x8C, 0x78, 0x23, -+ 0xD0, 0x89, 0x24, 0xD9, 0x6C, 0x35, 0x2C, 0x5D, -+ 0x8F, 0xBB, 0xFC, 0x10, 0xD0, 0xE2, 0x22, 0x7D, -+ 0xC8, 0x97, 0x9A, 0xEF, 0xC6, 0xB5, 0xA7, 0x4E, -+ 0x4E, 0x0E -+ } -+}; -+ -+/* HSM2.0 BROM NAND header for SPI NAND with 2KB page + 128B spare */ -+static const union hsm20_nand_boot_header hsm20_nand_hdr_2k_128_data = { -+ .data = { -+ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, -+ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, -+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, -+ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, -+ 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0xF8, 0x7E, 0xC1, 0x5D, 0x61, 0x54, 0xEA, 0x9F, -+ 0x5E, 0x66, 0x39, 0x66, 0x21, 0xFF, 0x8C, 0x3B, -+ 0xBE, 0xA7, 0x5A, 0x9E, 0xD7, 0xBD, 0x9E, 0x89, -+ 0xEE, 0x7E, 0x10, 0x31, 0x9A, 0x1D, 0x82, 0x49, -+ 0xA3, 0x4E, 0xD8, 0x47, 0xD7, 0x19, 0xF4, 0x2D, -+ 0x8E, 0x53 -+ } -+}; -+ -+/* HSM2.0 BROM NAND header for SPI NAND with 4KB page + 256B spare */ -+static const union hsm20_nand_boot_header hsm20_nand_hdr_4k_256_data = { -+ .data = { -+ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, -+ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, -+ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, -+ 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x79, 0x01, 0x1F, 0x86, 0x62, 0x6A, 0x43, 0xAE, -+ 0xE6, 0xF8, 0xDD, 0x5B, 0x29, 0xB7, 0xA2, 0x7F, -+ 0x29, 0x72, 0x54, 0x37, 0xBE, 0x50, 0xD4, 0x24, -+ 0xAB, 0x60, 0xF4, 0x44, 0x97, 0x3B, 0x65, 0x21, -+ 0x73, 0x24, 0x1F, 0x93, 0x0E, 0x9E, 0x96, 0x88, -+ 0x78, 0x6C -+ } -+}; -+ -+/* SPIM-NAND header for SPI NAND with 2KB page + 64B spare */ -+static const union spim_nand_boot_header spim_nand_hdr_2k_64_data = { -+ .data = { -+ 0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21, -+ 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, -+ 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, -+ 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x30, -+ 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ } -+}; -+ -+/* SPIM-NAND header for SPI NAND with 2KB page + 128B spare */ -+static const union spim_nand_boot_header spim_nand_hdr_2k_128_data = { -+ .data = { -+ 0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21, -+ 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, -+ 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, -+ 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x30, -+ 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ } -+}; -+ -+/* SPIM-NAND header for SPI NAND with 4KB page + 256B spare */ -+static const union spim_nand_boot_header spim_nand_hdr_4k_256_data = { -+ .data = { -+ 0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21, -+ 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, -+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x40, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x30, -+ 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ } -+}; -+ -+struct nand_header_type { - const char *name; -- const union nand_boot_header *data; -+ enum nand_boot_header_type type; -+ union { -+ const union nand_boot_header *ap; -+ const union hsm_nand_boot_header *hsm; -+ const union hsm20_nand_boot_header *hsm20; -+ const union spim_nand_boot_header *spim; -+ }; - } nand_headers[] = { - { - .name = "2k+64", -- .data = &snand_hdr_2k_64_data -+ .type = NAND_BOOT_AP_HEADER, -+ .ap = &snand_hdr_2k_64_data, - }, { - .name = "2k+120", -- .data = &snand_hdr_2k_128_data -+ .type = NAND_BOOT_AP_HEADER, -+ .ap = &snand_hdr_2k_128_data, - }, { - .name = "2k+128", -- .data = &snand_hdr_2k_128_data -+ .type = NAND_BOOT_AP_HEADER, -+ .ap = &snand_hdr_2k_128_data, - }, { - .name = "4k+256", -- .data = &snand_hdr_4k_256_data -+ .type = NAND_BOOT_AP_HEADER, -+ .ap = &snand_hdr_4k_256_data, - }, { - .name = "1g:2k+64", -- .data = &nand_hdr_1gb_2k_64_data -+ .type = NAND_BOOT_AP_HEADER, -+ .ap = &nand_hdr_1gb_2k_64_data, - }, { - .name = "2g:2k+64", -- .data = &nand_hdr_2gb_2k_64_data -+ .type = NAND_BOOT_AP_HEADER, -+ .ap = &nand_hdr_2gb_2k_64_data, - }, { - .name = "4g:2k+64", -- .data = &nand_hdr_4gb_2k_64_data -+ .type = NAND_BOOT_AP_HEADER, -+ .ap = &nand_hdr_4gb_2k_64_data, - }, { - .name = "2g:2k+128", -- .data = &nand_hdr_2gb_2k_128_data -+ .type = NAND_BOOT_AP_HEADER, -+ .ap = &nand_hdr_2gb_2k_128_data, - }, { - .name = "4g:2k+128", -- .data = &nand_hdr_4gb_2k_128_data -+ .type = NAND_BOOT_AP_HEADER, -+ .ap = &nand_hdr_4gb_2k_128_data, -+ }, { -+ .name = "hsm:2k+64", -+ .type = NAND_BOOT_HSM_HEADER, -+ .hsm = &hsm_nand_hdr_2k_64_data, -+ }, { -+ .name = "hsm:2k+128", -+ .type = NAND_BOOT_HSM_HEADER, -+ .hsm = &hsm_nand_hdr_2k_128_data, -+ }, { -+ .name = "hsm:4k+256", -+ .type = NAND_BOOT_HSM_HEADER, -+ .hsm = &hsm_nand_hdr_4k_256_data, -+ }, { -+ .name = "hsm20:2k+64", -+ .type = NAND_BOOT_HSM20_HEADER, -+ .hsm20 = &hsm20_nand_hdr_2k_64_data, -+ }, { -+ .name = "hsm20:2k+128", -+ .type = NAND_BOOT_HSM20_HEADER, -+ .hsm20 = &hsm20_nand_hdr_2k_128_data, -+ }, { -+ .name = "hsm20:4k+256", -+ .type = NAND_BOOT_HSM20_HEADER, -+ .hsm20 = &hsm20_nand_hdr_4k_256_data, -+ }, { -+ .name = "spim:2k+64", -+ .type = NAND_BOOT_SPIM_HEADER, -+ .spim = &spim_nand_hdr_2k_64_data, -+ }, { -+ .name = "spim:2k+128", -+ .type = NAND_BOOT_SPIM_HEADER, -+ .spim = &spim_nand_hdr_2k_128_data, -+ }, { -+ .name = "spim:4k+256", -+ .type = NAND_BOOT_SPIM_HEADER, -+ .spim = &spim_nand_hdr_4k_256_data, - } - }; - --const union nand_boot_header *mtk_nand_header_find(const char *name) -+const struct nand_header_type *mtk_nand_header_find(const char *name) - { - uint32_t i; - - for (i = 0; i < ARRAY_SIZE(nand_headers); i++) { - if (!strcmp(nand_headers[i].name, name)) -- return nand_headers[i].data; -+ return &nand_headers[i]; - } - - return NULL; - } - --uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand) -+uint32_t mtk_nand_header_size(const struct nand_header_type *hdr_nand) - { -- return 2 * le16_to_cpu(hdr_nand->pagesize); -+ switch (hdr_nand->type) { -+ case NAND_BOOT_HSM_HEADER: -+ return le32_to_cpu(hdr_nand->hsm->page_size); -+ -+ case NAND_BOOT_HSM20_HEADER: -+ return le32_to_cpu(hdr_nand->hsm20->page_size); -+ -+ case NAND_BOOT_SPIM_HEADER: -+ return le32_to_cpu(hdr_nand->spim->page_size); -+ -+ default: -+ return 2 * le16_to_cpu(hdr_nand->ap->pagesize); -+ } - } - - static int mtk_nand_header_ap_info(const void *ptr, -@@ -251,14 +542,45 @@ static int mtk_nand_header_ap_info(const - info->page_size = le16_to_cpu(nh->pagesize); - info->spare_size = le16_to_cpu(nh->oobsize); - info->gfh_offset = 2 * info->page_size; -+ info->snfi = true; - - return 0; - } - -+static int mtk_nand_header_hsm_info(const void *ptr, -+ struct nand_header_info *info) -+{ -+ union hsm_nand_boot_header *nh = (union hsm_nand_boot_header *)ptr; -+ -+ info->page_size = le16_to_cpu(nh->page_size); -+ info->spare_size = le16_to_cpu(nh->spare_size); -+ info->gfh_offset = info->page_size; -+ info->snfi = true; -+ -+ return 1; -+} -+ -+static int mtk_nand_header_spim_info(const void *ptr, -+ struct nand_header_info *info) -+{ -+ union spim_nand_boot_header *nh = (union spim_nand_boot_header *)ptr; -+ -+ info->page_size = le16_to_cpu(nh->page_size); -+ info->spare_size = le16_to_cpu(nh->spare_size); -+ info->gfh_offset = info->page_size; -+ info->snfi = false; -+ -+ return 1; -+} -+ - int mtk_nand_header_info(const void *ptr, struct nand_header_info *info) - { - if (!strcmp((char *)ptr, NAND_BOOT_NAME)) - return mtk_nand_header_ap_info(ptr, info); -+ else if (!strncmp((char *)ptr, HSM_NAND_BOOT_NAME, 8)) -+ return mtk_nand_header_hsm_info(ptr, info); -+ else if (!strncmp((char *)ptr, SPIM_NAND_BOOT_NAME, 8)) -+ return mtk_nand_header_spim_info(ptr, info); - - return -1; - } -@@ -273,14 +595,74 @@ bool is_mtk_nand_header(const void *ptr) - return false; - } - --uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void *ptr) -+static uint16_t crc16(const uint8_t *p, uint32_t len) -+{ -+ uint16_t crc = 0x4f4e; -+ uint32_t i; -+ -+ while (len--) { -+ crc ^= *p++ << 8; -+ for (i = 0; i < 8; i++) -+ crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0); -+ } -+ -+ return crc; -+} -+ -+static uint32_t mtk_nand_header_put_ap(const struct nand_header_type *hdr_nand, -+ void *ptr) - { -- union nand_boot_header *nh = (union nand_boot_header *)ptr; - int i; - - /* NAND device header, repeat 4 times */ -- for (i = 0; i < 4; i++) -- memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header)); -+ for (i = 0; i < 4; i++) { -+ memcpy(ptr, hdr_nand->ap, sizeof(*hdr_nand->ap)); -+ ptr += sizeof(*hdr_nand->ap); -+ } -+ -+ return le16_to_cpu(hdr_nand->ap->pagesize); -+} - -- return le16_to_cpu(hdr_nand->pagesize); -+static uint32_t mtk_nand_header_put_hsm(const struct nand_header_type *hdr_nand, -+ void *ptr) -+{ -+ memcpy(ptr, hdr_nand->hsm, sizeof(*hdr_nand->hsm)); -+ return 0; -+} -+ -+static uint32_t mtk_nand_header_put_hsm20(const struct nand_header_type *hdr_nand, -+ void *ptr) -+{ -+ memcpy(ptr, hdr_nand->hsm20, sizeof(*hdr_nand->hsm20)); -+ return 0; -+} -+ -+static uint32_t mtk_nand_header_put_spim(const struct nand_header_type *hdr_nand, -+ void *ptr) -+{ -+ uint16_t crc; -+ -+ memcpy(ptr, hdr_nand->spim, sizeof(*hdr_nand->spim)); -+ -+ crc = crc16(ptr, 0x4e); -+ memcpy(ptr + 0x4e, &crc, sizeof(uint16_t)); -+ -+ return 0; -+} -+ -+uint32_t mtk_nand_header_put(const struct nand_header_type *hdr_nand, void *ptr) -+{ -+ switch (hdr_nand->type) { -+ case NAND_BOOT_HSM_HEADER: -+ return mtk_nand_header_put_hsm(hdr_nand, ptr); -+ -+ case NAND_BOOT_HSM20_HEADER: -+ return mtk_nand_header_put_hsm20(hdr_nand, ptr); -+ -+ case NAND_BOOT_SPIM_HEADER: -+ return mtk_nand_header_put_spim(hdr_nand, ptr); -+ -+ default: -+ return mtk_nand_header_put_ap(hdr_nand, ptr); -+ } - } ---- a/tools/mtk_nand_headers.h -+++ b/tools/mtk_nand_headers.h -@@ -16,6 +16,7 @@ struct nand_header_info { - uint32_t page_size; - uint32_t spare_size; - uint32_t gfh_offset; -+ bool snfi; - }; - - /* AP BROM Header for NAND */ -@@ -39,15 +40,117 @@ union nand_boot_header { - uint8_t data[0x80]; - }; - -+/* HSM BROM Header for NAND */ -+union hsm_nand_boot_header { -+ struct { -+ char id[8]; -+ uint32_t version; /* Header version */ -+ uint32_t config; /* Header config */ -+ uint32_t sector_size; /* ECC step size */ -+ uint32_t fdm_size; /* User OOB size of a step */ -+ uint32_t fdm_ecc_size; /* ECC parity size of a step */ -+ uint32_t lbs; -+ uint32_t page_size; /* NAND page size */ -+ uint32_t spare_size; /* NAND page spare size */ -+ uint32_t page_per_block; /* Pages of one block */ -+ uint32_t blocks; /* Total blocks of NAND chip */ -+ uint32_t plane_sel_position; /* Plane bit position */ -+ uint32_t pll; /* Value of pll reg */ -+ uint32_t acccon; /* Value of access timing reg */ -+ uint32_t strobe_sel; /* Value of DQS selection reg*/ -+ uint32_t acccon1; /* Value of access timing reg */ -+ uint32_t dqs_mux; /* Value of DQS mux reg */ -+ uint32_t dqs_ctrl; /* Value of DQS control reg */ -+ uint32_t delay_ctrl; /* Value of delay ctrl reg */ -+ uint32_t latch_lat; /* Value of latch latency reg */ -+ uint32_t sample_delay; /* Value of sample delay reg */ -+ uint32_t driving; /* Value of driving reg */ -+ uint32_t bl_start; /* Bootloader start addr */ -+ uint32_t bl_end; /* Bootloader end addr */ -+ uint8_t ecc_parity[42]; /* ECC parity of this header */ -+ }; -+ -+ uint8_t data[0x8E]; -+}; -+ -+/* HSM2.0 BROM Header for NAND */ -+union hsm20_nand_boot_header { -+ struct { -+ char id[8]; -+ uint32_t version; /* Header version */ -+ uint32_t config; /* Header config */ -+ uint32_t sector_size; /* ECC step size */ -+ uint32_t fdm_size; /* User OOB size of a step */ -+ uint32_t fdm_ecc_size; /* ECC parity size of a step */ -+ uint32_t lbs; -+ uint32_t page_size; /* NAND page size */ -+ uint32_t spare_size; /* NAND page spare size */ -+ uint32_t page_per_block; /* Pages of one block */ -+ uint32_t blocks; /* Total blocks of NAND chip */ -+ uint32_t plane_sel_position; /* Plane bit position */ -+ uint32_t pll; /* Value of pll reg */ -+ uint32_t acccon; /* Value of access timing reg */ -+ uint32_t strobe_sel; /* Value of DQS selection reg*/ -+ uint32_t acccon1; /* Value of access timing reg */ -+ uint32_t dqs_mux; /* Value of DQS mux reg */ -+ uint32_t dqs_ctrl; /* Value of DQS control reg */ -+ uint32_t delay_ctrl; /* Value of delay ctrl reg */ -+ uint32_t latch_lat; /* Value of latch latency reg */ -+ uint32_t sample_delay; /* Value of sample delay reg */ -+ uint32_t driving; /* Value of driving reg */ -+ uint32_t reserved; -+ uint32_t bl0_start; /* Bootloader start addr */ -+ uint32_t bl0_end; /* Bootloader end addr */ -+ uint32_t bl0_type; /* Bootloader type */ -+ uint8_t bl_reserve[84]; -+ uint8_t ecc_parity[42]; /* ECC parity of this header */ -+ }; -+ -+ uint8_t data[0xEA]; -+}; -+ -+/* SPIM BROM Header for SPI-NAND */ -+union spim_nand_boot_header { -+ struct { -+ char id[8]; -+ uint32_t version; /* Header version */ -+ uint32_t config; /* Header config */ -+ uint32_t page_size; /* NAND page size */ -+ uint32_t spare_size; /* NAND page spare size */ -+ uint16_t page_per_block; /* Pages of one block */ -+ uint16_t plane_sel_position; /* Plane bit position */ -+ uint16_t reserve_reg; -+ uint16_t reserve_val; -+ uint16_t ecc_error; /* ECC error reg addr */ -+ uint16_t ecc_mask; /* ECC error bit mask */ -+ uint32_t bl_start; /* Bootloader start addr */ -+ uint32_t bl_end; /* Bootloader end addr */ -+ uint8_t ecc_parity[32]; /* ECC parity of this header */ -+ uint32_t integrity_crc; /* CRC of this header */ -+ }; -+ -+ uint8_t data[0x50]; -+}; -+ -+enum nand_boot_header_type { -+ NAND_BOOT_AP_HEADER, -+ NAND_BOOT_HSM_HEADER, -+ NAND_BOOT_HSM20_HEADER, -+ NAND_BOOT_SPIM_HEADER -+}; -+ - #define NAND_BOOT_NAME "BOOTLOADER!" - #define NAND_BOOT_VERSION "V006" - #define NAND_BOOT_ID "NFIINFO" - -+#define HSM_NAND_BOOT_NAME "NANDCFG!" -+#define SPIM_NAND_BOOT_NAME "SPINAND!" -+ - /* Find nand header data by name */ --const union nand_boot_header *mtk_nand_header_find(const char *name); -+const struct nand_header_type *mtk_nand_header_find(const char *name); - - /* Device header size using this nand header */ --uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand); -+uint32_t mtk_nand_header_size(const struct nand_header_type *hdr_nand); - - /* Get nand info from nand header (page size, spare size, ...) */ - int mtk_nand_header_info(const void *ptr, struct nand_header_info *info); -@@ -56,6 +159,7 @@ int mtk_nand_header_info(const void *ptr - bool is_mtk_nand_header(const void *ptr); - - /* Generate Device header using give nand header */ --uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void *ptr); -+uint32_t mtk_nand_header_put(const struct nand_header_type *hdr_nand, -+ void *ptr); - - #endif /* _MTK_NAND_HEADERS_H */ diff --git a/tools/mkimage/patches/030-allow-to-use-different-magic.patch b/tools/mkimage/patches/030-allow-to-use-different-magic.patch index 591edf24e..d88f1cf94 100644 --- a/tools/mkimage/patches/030-allow-to-use-different-magic.patch +++ b/tools/mkimage/patches/030-allow-to-use-different-magic.patch @@ -52,14 +52,14 @@ This patch makes it possible to set a custom image magic. +++ b/tools/default_image.c @@ -56,7 +56,7 @@ static int image_verify_header(unsigned */ - memcpy(hdr, ptr, sizeof(image_header_t)); + memcpy(hdr, ptr, sizeof(struct legacy_img_hdr)); - if (be32_to_cpu(hdr->ih_magic) != IH_MAGIC) { + if (be32_to_cpu(hdr->ih_magic) != params->magic) { debug("%s: Bad Magic Number: \"%s\" is no valid image\n", params->cmdname, params->imagefile); return -FDT_ERR_BADMAGIC; -@@ -120,7 +120,7 @@ static void image_set_header(void *ptr, +@@ -119,7 +119,7 @@ static void image_set_header(void *ptr, } /* Build new header */