diff --git a/.github/labeler.yml b/.github/labeler.yml index c0ffdaf05d4..6d53d581063 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -5,8 +5,8 @@ - "target/linux/apm821xx/**" "target/archs38": - "target/linux/archs38/**" -"target/armvirt": - - "target/linux/armvirt/**" +"target/armsr": + - "target/linux/armsr/**" "target/at91": - "target/linux/at91/**" - "package/boot/at91bootstrap/**" @@ -94,6 +94,10 @@ - "target/linux/rockchip/**" - "package/boot/arm-trusted-firmware-rockchip/**" - "package/boot/uboot-rockchip/**" +"target/sifiveu": + - "target/linux/sifiveu/**" + - "package/boot/uboot-sifiveu/**" + - "package/boot/opensbi/**" "target/sunxi": - "target/linux/sunxi/**" - "package/boot/arm-trusted-firmware-sunxi/**" diff --git a/config/Config-images.in b/config/Config-images.in index d92c31ec5fc..ea7b3d37c3d 100644 --- a/config/Config-images.in +++ b/config/Config-images.in @@ -204,12 +204,12 @@ menu "Target Images" config GRUB_EFI_IMAGES bool "Build GRUB EFI images (Linux x86 or x86_64 host only)" - depends on TARGET_x86 || TARGET_armvirt + depends on TARGET_x86 || TARGET_armsr depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS select PACKAGE_grub2 if TARGET_x86 select PACKAGE_grub2-efi if TARGET_x86 select PACKAGE_grub2-bios-setup if TARGET_x86 - select PACKAGE_grub2-efi-arm if TARGET_armvirt + select PACKAGE_grub2-efi-arm if TARGET_armsr select PACKAGE_kmod-fs-vfat default y @@ -267,7 +267,7 @@ menu "Target Images" config VMDK_IMAGES bool "Build VMware image files (VMDK)" - depends on TARGET_x86 || TARGET_armvirt + depends on TARGET_x86 || TARGET_armsr depends on GRUB_IMAGES || GRUB_EFI_IMAGES select PACKAGE_kmod-e1000 @@ -279,7 +279,7 @@ menu "Target Images" config TARGET_IMAGES_GZIP bool "GZip images" - depends on TARGET_ROOTFS_EXT4FS || TARGET_x86 || TARGET_armvirt || TARGET_malta + depends on TARGET_ROOTFS_EXT4FS || TARGET_x86 || TARGET_armsr || TARGET_malta default y comment "Image Options" @@ -292,7 +292,7 @@ menu "Target Images" depends on USES_BOOT_PART default 8 if TARGET_apm821xx_sata default 64 if TARGET_bcm27xx - default 128 if TARGET_armvirt + default 128 if TARGET_armsr default 16 config TARGET_ROOTFS_PARTSIZE diff --git a/include/kernel-5.15 b/include/kernel-5.15 index 4c18bc35c22..6db270a3741 100644 --- a/include/kernel-5.15 +++ b/include/kernel-5.15 @@ -1,2 +1,2 @@ -LINUX_VERSION-5.15 = .114 -LINUX_KERNEL_HASH-5.15.114 = e981ea5d219f77735bf5a3f7e84a8af578df8ac3e1c4ff1b0649e2b0795277d2 +LINUX_VERSION-5.15 = .116 +LINUX_KERNEL_HASH-5.15.116 = f617c9d1bb5326cc93495938f43eb8cb9aea9d2f451e5a99bce2893f296e179a diff --git a/include/kernel-6.1 b/include/kernel-6.1 index c8d2ec32dac..51dd7ec52ac 100644 --- a/include/kernel-6.1 +++ b/include/kernel-6.1 @@ -1,2 +1,2 @@ -LINUX_VERSION-6.1 = .32 -LINUX_KERNEL_HASH-6.1.32 = 7c88b7a09ba2b9e47b78eba2b32b1db6a4d89636f7ddd586545f9671a2521a6c \ No newline at end of file +LINUX_VERSION-6.1 = .33 +LINUX_KERNEL_HASH-6.1.33 = b87d6ba8ea7328e8007a7ea9171d1aa0d540d95eacfcab09578e0a3b623dd2cd \ No newline at end of file diff --git a/include/u-boot.mk b/include/u-boot.mk index 8945e8e2b8f..2b8106410f5 100644 --- a/include/u-boot.mk +++ b/include/u-boot.mk @@ -83,6 +83,9 @@ endef define Build/Configure/U-Boot +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) $(UBOOT_CONFIGURE_VARS) $(UBOOT_CONFIG)_config + $(if $(strip $(UBOOT_CUSTOMIZE_CONFIG)), + $(PKG_BUILD_DIR)/scripts/config --file $(PKG_BUILD_DIR)/.config $(UBOOT_CUSTOMIZE_CONFIG) + +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) $(UBOOT_CONFIGURE_VARS) oldconfig) endef DTC=$(wildcard $(LINUX_DIR)/scripts/dtc/dtc) diff --git a/package/boot/grub2/Makefile b/package/boot/grub2/Makefile index 50bf96360d6..865feee9ad1 100644 --- a/package/boot/grub2/Makefile +++ b/package/boot/grub2/Makefile @@ -41,7 +41,7 @@ endef Package/grub2=$(call Package/grub2/Default,x86,pc) Package/grub2-efi=$(call Package/grub2/Default,x86,efi) -Package/grub2-efi-arm=$(call Package/grub2/Default,armvirt,efi) +Package/grub2-efi-arm=$(call Package/grub2/Default,armsr,efi) define Package/grub2-editenv CATEGORY:=Utilities diff --git a/package/boot/uboot-armsr/Makefile b/package/boot/uboot-armsr/Makefile new file mode 100644 index 00000000000..ce53d19b796 --- /dev/null +++ b/package/boot/uboot-armsr/Makefile @@ -0,0 +1,36 @@ +include $(TOPDIR)/rules.mk + +PKG_VERSION:=2023.04 +PKG_RELEASE:=1 + +PKG_HASH:=e31cac91545ff41b71cec5d8c22afd695645cd6e2a442ccdacacd60534069341 + +include $(INCLUDE_DIR)/u-boot.mk +include $(INCLUDE_DIR)/package.mk + +define U-Boot/Default + BUILD_TARGET:=armsr +endef + +define U-Boot/qemu_armv7 + NAME:=QEMU ARM Virtual Machine 32-bit + BUILD_SUBTARGET:=armv7 + BUILD_DEVICES:=generic + UBOOT_CONFIG:=qemu_arm +endef + +define U-Boot/qemu_armv8 + NAME:=QEMU ARM Virtual Machine 64-bit + BUILD_SUBTARGET:=armv8 + BUILD_DEVICES:=generic + UBOOT_CONFIG:=qemu_arm64 +endef + +UBOOT_TARGETS := \ + qemu_armv7 \ + qemu_armv8 + +UBOOT_CUSTOMIZE_CONFIG := \ + --enable CMD_EFIDEBUG + +$(eval $(call BuildPackage/U-Boot)) diff --git a/package/boot/uboot-armsr/patches/001-v2023.07-bootstd-Use-blk-uclass-device-numbers-to-set-efi-bootdev.patch b/package/boot/uboot-armsr/patches/001-v2023.07-bootstd-Use-blk-uclass-device-numbers-to-set-efi-bootdev.patch new file mode 100644 index 00000000000..f4c81189521 --- /dev/null +++ b/package/boot/uboot-armsr/patches/001-v2023.07-bootstd-Use-blk-uclass-device-numbers-to-set-efi-bootdev.patch @@ -0,0 +1,62 @@ +From: Simon Glass +To: U-Boot Mailing List +Subject: [PATCH v10 7/9] bootstd: Use blk uclass device numbers to set efi + bootdev +Date: Mon, 24 Apr 2023 13:49:50 +1200 +Message-ID: + <20230424134946.v10.7.Ia5f5e39c882ac22b5f71c4d576941b34e868eeba@changeid> + +From: Mathew McBride + +When loading a file from a block device, efiload_read_file +was using the seq_num of the device (e.g "35" of virtio_blk#35) +instead of the block device id (e.g what you get from running +the corresponding device scan command, like "virtio 0") + +This cause EFI booting from these devices to fail as an +invalid device number is passed to blk_get_device_part_str: + + Scanning bootdev 'virtio-blk#35.bootdev': + distro_efi_read_bootflow_file start (efi,fname=) + distro_efi_read_bootflow_file start (efi,fname=) + setting bootdev virtio, 35, efi/boot/bootaa64.efi, 00000000beef9a40, 170800 + efi_dp_from_name calling blk_get_device_part_str + dev=virtio devnr=35 path=efi/boot/bootaa64.efi + blk_get_device_part_str (virtio,35) + blk_get_device_by_str (virtio, 35) + ** Bad device specification virtio 35 ** + Using default device tree: dtb/qemu-arm.dtb + No device tree available + 0 efi ready virtio 1 virtio-blk#35.bootdev.par efi/boot/bootaa64.efi + ** Booting bootflow 'virtio-blk#35.bootdev.part_1' with efi + blk_get_device_part_str (virtio,0:1) + blk_get_device_by_str (virtio, 0) + No UEFI binary known at beef9a40 (image buf=00000000beef9a40,addr=0000000000000000) + Boot failed (err=-22) + +Signed-off-by: Mathew McBride +Signed-off-by: Simon Glass +Signed-off-by: Petr Štetiar [backport to 2023.04] +--- + +(no changes since v8) + +Changes in v8: +- Add new patch to use blk uclass device numbers to set efi bootdev + + boot/bootmeth_efi.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/boot/bootmeth_efi.c ++++ b/boot/bootmeth_efi.c +@@ -117,7 +117,9 @@ static int efiload_read_file(struct blk_ + * this can go away. + */ + media_dev = dev_get_parent(bflow->dev); +- snprintf(devnum_str, sizeof(devnum_str), "%x", dev_seq(media_dev)); ++ snprintf(devnum_str, sizeof(devnum_str), "%x:%x", ++ desc ? desc->devnum : dev_seq(media_dev), ++ bflow->part); + + strlcpy(dirname, bflow->fname, sizeof(dirname)); + last_slash = strrchr(dirname, '/'); diff --git a/package/boot/uboot-envtools/files/ipq807x b/package/boot/uboot-envtools/files/ipq807x index 0185c2c8e6f..345cdadebee 100644 --- a/package/boot/uboot-envtools/files/ipq807x +++ b/package/boot/uboot-envtools/files/ipq807x @@ -36,6 +36,11 @@ xiaomi,ax9000) [ -n "$idx2" ] && \ ubootenv_add_uci_sys_config "/dev/mtd$idx2" "0x0" "0x10000" "0x20000" ;; +prpl,haze) + mmcpart="$(find_mmc_part 0:APPSBLENV)" + [ -n "$mmcpart" ] && \ + ubootenv_add_uci_config "$mmcpart" "0x0" "0x40000" "0x400" "0x100" + ;; qnap,301w) idx="$(find_mtd_index 0:appsblenv)" [ -n "$idx" ] && \ diff --git a/package/boot/uboot-envtools/files/ramips b/package/boot/uboot-envtools/files/ramips index 6f351af2122..b3f37c7c3eb 100644 --- a/package/boot/uboot-envtools/files/ramips +++ b/package/boot/uboot-envtools/files/ramips @@ -39,6 +39,7 @@ ampedwireless,ally-r1900k) ;; beeline,smartbox-giga|\ beeline,smartbox-turbo|\ +beeline,smartbox-turbo-plus|\ etisalat,s3|\ rostelecom,rt-sf-1) ubootenv_add_uci_config "/dev/mtd0" "0x80000" "0x1000" "0x20000" diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile index afdb49b2e99..0c6941050b0 100644 --- a/package/firmware/ipq-wifi/Makefile +++ b/package/firmware/ipq-wifi/Makefile @@ -6,9 +6,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/firmware/qca-wireless.git -PKG_SOURCE_DATE:=2023-05-22 -PKG_SOURCE_VERSION:=0f73d32e641c4f17e64597da0e6c40ed3cbebe69 -PKG_MIRROR_HASH:=70bd8ecda004528ec74de078d00df792f92322c58c4ec4b0630d1da097a8bc89 +PKG_SOURCE_DATE:=2023-06-03 +PKG_SOURCE_VERSION:=cd9c30ca47b8e5388b770c523a7f6b8b969e2f92 +PKG_MIRROR_HASH:=45e623fcc512b514ade0f22e217275536aa8de4afba7dfdb11696482b8fa71a2 PKG_FLAGS:=nonshared @@ -34,6 +34,7 @@ ALLWIFIBOARDS:= \ edgecore_eap102 \ edimax_cax1800 \ netgear_wax218 \ + prpl_haze \ qnap_301w \ redmi_ax6 \ wallys_dr40x9 \ @@ -120,6 +121,7 @@ $(eval $(call generate-ipq-wifi-package,edgecore_eap102,Edgecore EAP102)) $(eval $(call generate-ipq-wifi-package,edimax_cax1800,Edimax CAX1800)) $(eval $(call generate-ipq-wifi-package,netgear_wax218,Netgear WAX218)) $(eval $(call generate-ipq-wifi-package,qnap_301w,QNAP 301w)) +$(eval $(call generate-ipq-wifi-package,prpl_haze,prpl Haze)) $(eval $(call generate-ipq-wifi-package,redmi_ax6,Redmi AX6)) $(eval $(call generate-ipq-wifi-package,wallys_dr40x9,Wallys DR40X9)) $(eval $(call generate-ipq-wifi-package,xiaomi_ax3600,Xiaomi AX3600)) diff --git a/package/firmware/layerscape/ls-dpl/Makefile b/package/firmware/layerscape/ls-dpl/Makefile index e3c84e98288..6c53b454170 100644 --- a/package/firmware/layerscape/ls-dpl/Makefile +++ b/package/firmware/layerscape/ls-dpl/Makefile @@ -12,7 +12,7 @@ PKG_VERSION:=21.08 PKG_RELEASE:=3 PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://source.codeaurora.org/external/qoriq/qoriq-components/mc-utils +PKG_SOURCE_URL:=https://github.com/nxp-qoriq/mc-utils PKG_SOURCE_VERSION:=LSDK-21.08 PKG_MIRROR_HASH:=372498ff4b5c8a1ac64ead5856d03ee021332f57771989ed6fe066745372b242 diff --git a/package/kernel/linux/modules/netdevices.mk b/package/kernel/linux/modules/netdevices.mk index d2cc67d1644..33e7f1bc306 100644 --- a/package/kernel/linux/modules/netdevices.mk +++ b/package/kernel/linux/modules/netdevices.mk @@ -142,7 +142,7 @@ $(eval $(call KernelPackage,mii)) define KernelPackage/mdio-devres SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=Supports MDIO device registration - DEPENDS:=+kmod-libphy +(TARGET_armvirt||TARGET_bcm27xx_bcm2708||TARGET_malta||TARGET_tegra):kmod-of-mdio + DEPENDS:=+kmod-libphy +(TARGET_armsr||TARGET_bcm27xx_bcm2708||TARGET_malta||TARGET_tegra):kmod-of-mdio KCONFIG:=CONFIG_MDIO_DEVRES HIDDEN:=1 FILES:=$(LINUX_DIR)/drivers/net/phy/mdio_devres.ko @@ -159,7 +159,7 @@ $(eval $(call KernelPackage,mdio-devres)) define KernelPackage/mdio-gpio SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:= Supports GPIO lib-based MDIO busses - DEPENDS:=+kmod-libphy @GPIO_SUPPORT +(TARGET_armvirt||TARGET_bcm27xx_bcm2708||TARGET_malta||TARGET_tegra):kmod-of-mdio + DEPENDS:=+kmod-libphy @GPIO_SUPPORT +(TARGET_armsr||TARGET_bcm27xx_bcm2708||TARGET_malta||TARGET_tegra):kmod-of-mdio KCONFIG:= \ CONFIG_MDIO_BITBANG \ CONFIG_MDIO_GPIO @@ -438,7 +438,7 @@ $(eval $(call KernelPackage,switch-rtl8306)) define KernelPackage/switch-rtl8366-smi SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=Realtek RTL8366 SMI switch interface support - DEPENDS:=@GPIO_SUPPORT +kmod-swconfig +(TARGET_armvirt||TARGET_bcm27xx_bcm2708||TARGET_malta||TARGET_tegra):kmod-of-mdio + DEPENDS:=@GPIO_SUPPORT +kmod-swconfig +(TARGET_armsr||TARGET_bcm27xx_bcm2708||TARGET_malta||TARGET_tegra):kmod-of-mdio KCONFIG:=CONFIG_RTL8366_SMI FILES:=$(LINUX_DIR)/drivers/net/phy/rtl8366_smi.ko AUTOLOAD:=$(call AutoLoad,42,rtl8366_smi,1) @@ -1544,7 +1544,7 @@ $(eval $(call KernelPackage,lan743x)) define KernelPackage/amazon-ena SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=Elastic Network Adapter (for Amazon AWS) - DEPENDS:=@TARGET_x86_64||TARGET_armvirt_64 + DEPENDS:=@TARGET_x86_64||TARGET_armsr_armv8 KCONFIG:=CONFIG_ENA_ETHERNET FILES:=$(LINUX_DIR)/drivers/net/ethernet/amazon/ena/ena.ko AUTOLOAD:=$(call AutoLoad,12,ena) diff --git a/package/kernel/qca-ssdk/patches/0002-SSDK-replace-ioremap_nocache-with-ioremap.patch b/package/kernel/qca-ssdk/patches/0001-SSDK-replace-ioremap_nocache-with-ioremap.patch similarity index 96% rename from package/kernel/qca-ssdk/patches/0002-SSDK-replace-ioremap_nocache-with-ioremap.patch rename to package/kernel/qca-ssdk/patches/0001-SSDK-replace-ioremap_nocache-with-ioremap.patch index 5589c8e2298..2b659e1322e 100644 --- a/package/kernel/qca-ssdk/patches/0002-SSDK-replace-ioremap_nocache-with-ioremap.patch +++ b/package/kernel/qca-ssdk/patches/0001-SSDK-replace-ioremap_nocache-with-ioremap.patch @@ -1,7 +1,7 @@ -From 845a89b05aae807fb837f8e8f27f95c89de6023f Mon Sep 17 00:00:00 2001 +From 1e46d596701fedb751a669666a74677344fb8724 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Wed, 12 May 2021 13:45:45 +0200 -Subject: [PATCH 02/11] SSDK: replace ioremap_nocache with ioremap +Subject: [PATCH 01/14] SSDK: replace ioremap_nocache with ioremap ioremap_nocache was dropped upstream, simply use the generic variety. diff --git a/package/kernel/qca-ssdk/patches/0003-SSDK-platform-use-of_mdio_find_bus-to-get-MDIO-bus.patch b/package/kernel/qca-ssdk/patches/0002-SSDK-platform-use-of_mdio_find_bus-to-get-MDIO-bus.patch similarity index 91% rename from package/kernel/qca-ssdk/patches/0003-SSDK-platform-use-of_mdio_find_bus-to-get-MDIO-bus.patch rename to package/kernel/qca-ssdk/patches/0002-SSDK-platform-use-of_mdio_find_bus-to-get-MDIO-bus.patch index f9535fb3874..21b3491c6f7 100644 --- a/package/kernel/qca-ssdk/patches/0003-SSDK-platform-use-of_mdio_find_bus-to-get-MDIO-bus.patch +++ b/package/kernel/qca-ssdk/patches/0002-SSDK-platform-use-of_mdio_find_bus-to-get-MDIO-bus.patch @@ -1,7 +1,7 @@ -From 85f988dbc15559a5a2fee606e6ef400aa39fe444 Mon Sep 17 00:00:00 2001 +From 60d2b72cacd43796def9b4bd69a9e0e84be9d2e1 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Wed, 12 May 2021 17:15:46 +0200 -Subject: [PATCH 03/11] SSDK: platform: use of_mdio_find_bus() to get MDIO bus +Subject: [PATCH 02/14] SSDK: platform: use of_mdio_find_bus() to get MDIO bus Kernel has a generic of_mdio_find_bus() which can get the appropriate MDIO bus based on the DT node. diff --git a/package/kernel/qca-ssdk/patches/0004-SSDK-dts-fix-of_get_mac_address.patch b/package/kernel/qca-ssdk/patches/0003-SSDK-dts-fix-of_get_mac_address.patch similarity index 91% rename from package/kernel/qca-ssdk/patches/0004-SSDK-dts-fix-of_get_mac_address.patch rename to package/kernel/qca-ssdk/patches/0003-SSDK-dts-fix-of_get_mac_address.patch index 1dd948643f2..c004f4acd88 100644 --- a/package/kernel/qca-ssdk/patches/0004-SSDK-dts-fix-of_get_mac_address.patch +++ b/package/kernel/qca-ssdk/patches/0003-SSDK-dts-fix-of_get_mac_address.patch @@ -1,7 +1,7 @@ -From 079c20aa182c6b623d49e1f375e022dedac7373c Mon Sep 17 00:00:00 2001 +From c1b6fa42a160763b574dd52aa4845718e4cd0ea6 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 13 Aug 2021 20:03:21 +0200 -Subject: [PATCH 04/11] SSDK: dts: fix of_get_mac_address() +Subject: [PATCH 03/14] SSDK: dts: fix of_get_mac_address() Recently OpenWrt backported the updated of_get_mac_address() function which returns and error code instead. diff --git a/package/kernel/qca-ssdk/patches/0006-qca8081-convert-to-5.11-IRQ-model.patch b/package/kernel/qca-ssdk/patches/0004-qca8081-convert-to-5.11-IRQ-model.patch similarity index 94% rename from package/kernel/qca-ssdk/patches/0006-qca8081-convert-to-5.11-IRQ-model.patch rename to package/kernel/qca-ssdk/patches/0004-qca8081-convert-to-5.11-IRQ-model.patch index 4eb7483d2bc..1e496ad9810 100644 --- a/package/kernel/qca-ssdk/patches/0006-qca8081-convert-to-5.11-IRQ-model.patch +++ b/package/kernel/qca-ssdk/patches/0004-qca8081-convert-to-5.11-IRQ-model.patch @@ -1,7 +1,7 @@ -From 9278b2794d984f5a8ec2350b9607a35aea2cc106 Mon Sep 17 00:00:00 2001 +From aaac91b5e8756dce1c0242d58074a0b5d4607b57 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 24 Dec 2021 20:02:32 +0100 -Subject: [PATCH 06/11] qca8081: convert to 5.11 IRQ model +Subject: [PATCH 04/14] 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. diff --git a/package/kernel/qca-ssdk/patches/0005-SSDK-config-add-kernel-5.15.patch b/package/kernel/qca-ssdk/patches/0005-SSDK-config-add-kernel-5.15.patch deleted file mode 100644 index 7b19f5d12cb..00000000000 --- a/package/kernel/qca-ssdk/patches/0005-SSDK-config-add-kernel-5.15.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 0c509f8d8e5a6a03933a112d4487fd1c005442d6 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Fri, 24 Dec 2021 19:39:02 +0100 -Subject: [PATCH 05/11] SSDK: config: add kernel 5.15 - -This is purely to identify it and be able to set -flags correctly. - -Signed-off-by: Robert Marko ---- - config | 6 +++++- - make/linux_opt.mk | 4 ++-- - 2 files changed, 7 insertions(+), 3 deletions(-) - ---- a/config -+++ b/config -@@ -24,6 +24,10 @@ ifeq ($(KVER),$(filter 5.4%,$(KVER))) - OS_VER=5_4 - endif - -+ifeq ($(KVER),$(filter 5.15%,$(KVER))) -+OS_VER=5_15 -+endif -+ - ifeq ($(KVER), 3.4.0) - OS_VER=3_4 - endif -@@ -132,7 +136,7 @@ ifeq ($(ARCH), arm) - endif - - 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.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 ---- a/make/linux_opt.mk -+++ b/make/linux_opt.mk -@@ -437,7 +437,7 @@ ifeq (KSLIB, $(MODULE_TYPE)) - KASAN_SHADOW_SCALE_SHIFT := 3 - endif - -- ifeq (5_4, $(OS_VER)) -+ ifeq (5_4 5_15, $(OS_VER)) - ifeq ($(ARCH), arm64) - KASAN_OPTION += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT) - endif -@@ -468,7 +468,7 @@ ifeq (KSLIB, $(MODULE_TYPE)) - - endif - -- ifeq ($(OS_VER),$(filter 4_4 5_4, $(OS_VER))) -+ ifeq ($(OS_VER),$(filter 4_4 5_4 5_15, $(OS_VER))) - MODULE_CFLAG += -DKVER34 - MODULE_CFLAG += -DKVER32 - MODULE_CFLAG += -DLNX26_22 diff --git a/package/kernel/qca-ssdk/patches/0007-qca807x-add-a-LED-quirk-for-Xiaomi-AX9000.patch b/package/kernel/qca-ssdk/patches/0005-qca807x-add-a-LED-quirk-for-Xiaomi-AX9000.patch similarity index 95% rename from package/kernel/qca-ssdk/patches/0007-qca807x-add-a-LED-quirk-for-Xiaomi-AX9000.patch rename to package/kernel/qca-ssdk/patches/0005-qca807x-add-a-LED-quirk-for-Xiaomi-AX9000.patch index b8ebb08047a..6ff92ab95a9 100644 --- a/package/kernel/qca-ssdk/patches/0007-qca807x-add-a-LED-quirk-for-Xiaomi-AX9000.patch +++ b/package/kernel/qca-ssdk/patches/0005-qca807x-add-a-LED-quirk-for-Xiaomi-AX9000.patch @@ -1,7 +1,7 @@ -From 20a7945b82a4aefcb9ca0a14978412e4ae0057c9 Mon Sep 17 00:00:00 2001 +From 37255b97a9170f6dd1604931f0d7a8f847be5b5d Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Tue, 11 Jan 2022 00:28:42 +0100 -Subject: [PATCH 07/11] qca807x: add a LED quirk for Xiaomi AX9000 +Subject: [PATCH 05/14] qca807x: add a LED quirk for Xiaomi AX9000 Xiaomi AX9000 has a single LED for each of 4 gigabit ethernet ports that are connected to QCA8075, and that LED is connected to the 100M LED pin. diff --git a/package/kernel/qca-ssdk/patches/0008-qca807x-add-a-LED-quirk-for-Xiaomi-AX3600.patch b/package/kernel/qca-ssdk/patches/0006-qca807x-add-a-LED-quirk-for-Xiaomi-AX3600.patch similarity index 89% rename from package/kernel/qca-ssdk/patches/0008-qca807x-add-a-LED-quirk-for-Xiaomi-AX3600.patch rename to package/kernel/qca-ssdk/patches/0006-qca807x-add-a-LED-quirk-for-Xiaomi-AX3600.patch index 27423af7ead..6e044c7466d 100644 --- a/package/kernel/qca-ssdk/patches/0008-qca807x-add-a-LED-quirk-for-Xiaomi-AX3600.patch +++ b/package/kernel/qca-ssdk/patches/0006-qca807x-add-a-LED-quirk-for-Xiaomi-AX3600.patch @@ -1,7 +1,7 @@ -From bad774f43ec253e7e743e23bde87444c9d9cefdc Mon Sep 17 00:00:00 2001 +From 1eaed6c8d72cb07e221a94d05615ae45b60ffd82 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Wed, 26 Jan 2022 14:47:33 +0100 -Subject: [PATCH 08/11] qca807x: add a LED quirk for Xiaomi AX3600 +Subject: [PATCH 06/14] qca807x: add a LED quirk for Xiaomi AX3600 AX3600 requires the same LED quirk so that PHY LED-s will blink even once Linux resets the PHY. diff --git a/package/kernel/qca-ssdk/patches/0009-include-fix-compilation-error-for-parse_uci_option.patch b/package/kernel/qca-ssdk/patches/0007-include-fix-compilation-error-for-parse_uci_option.patch similarity index 78% rename from package/kernel/qca-ssdk/patches/0009-include-fix-compilation-error-for-parse_uci_option.patch rename to package/kernel/qca-ssdk/patches/0007-include-fix-compilation-error-for-parse_uci_option.patch index 1cdb47b2c14..6b084a844d2 100644 --- a/package/kernel/qca-ssdk/patches/0009-include-fix-compilation-error-for-parse_uci_option.patch +++ b/package/kernel/qca-ssdk/patches/0007-include-fix-compilation-error-for-parse_uci_option.patch @@ -1,7 +1,7 @@ -From be352dd54d163c005611906ac6b87692c9b8a1e6 Mon Sep 17 00:00:00 2001 +From adc75660a50c5b7a16032921a30a0eaedc8b826f Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Sat, 7 May 2022 19:03:55 +0200 -Subject: [PATCH 09/11] include: fix compilation error for parse_uci_option +Subject: [PATCH 07/14] include: fix compilation error for parse_uci_option Fix missing include for parse_uci_option diff --git a/package/kernel/qca-ssdk/patches/0010-QSDK-config-Avoid-Werror-heroics.patch b/package/kernel/qca-ssdk/patches/0008-QSDK-config-Avoid-Werror-heroics.patch similarity index 83% rename from package/kernel/qca-ssdk/patches/0010-QSDK-config-Avoid-Werror-heroics.patch rename to package/kernel/qca-ssdk/patches/0008-QSDK-config-Avoid-Werror-heroics.patch index 8eff0a9958e..30b4e4be4f9 100644 --- a/package/kernel/qca-ssdk/patches/0010-QSDK-config-Avoid-Werror-heroics.patch +++ b/package/kernel/qca-ssdk/patches/0008-QSDK-config-Avoid-Werror-heroics.patch @@ -1,7 +1,7 @@ -From ecd1e0c57fdf7f8916fa20f085e08bb4b6ba0396 Mon Sep 17 00:00:00 2001 +From d70d013ac1090565ebb71875f5bdc70840807428 Mon Sep 17 00:00:00 2001 From: Alexandru Gagniuc Date: Fri, 23 Sep 2022 08:21:13 -0500 -Subject: [PATCH 10/11] QSDK: config: Avoid -Werror heroics +Subject: [PATCH 08/14] QSDK: config: Avoid -Werror heroics Trying to compile the QSDK with warnings as errors is a very brave endeavor. It's also stupid as it doesn't work on ipq60xx: @@ -19,10 +19,10 @@ Signed-off-by: Alexandru Gagniuc --- a/config +++ b/config -@@ -137,7 +137,7 @@ endif +@@ -133,7 +133,7 @@ endif ifeq ($(ARCH), arm64) - ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4% 5.15%,$(KVER))) + ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4%,$(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 + CPU_CFLAG= -DMODULE -Os -pipe -march=armv8-a -mcpu=cortex-a53+crypto -fno-caller-saves -fno-strict-aliasing -fno-common -Wno-format-security -Wno-pointer-sign -Wno-unused-but-set-variable -Wno-error=unused-result -mcmodel=large endif diff --git a/package/kernel/qca-ssdk/patches/0011-Revert-qca-ssdk-remove-bridge-fdb-entry-for-the-auth.patch b/package/kernel/qca-ssdk/patches/0009-Revert-qca-ssdk-remove-bridge-fdb-entry-for-the-auth.patch similarity index 91% rename from package/kernel/qca-ssdk/patches/0011-Revert-qca-ssdk-remove-bridge-fdb-entry-for-the-auth.patch rename to package/kernel/qca-ssdk/patches/0009-Revert-qca-ssdk-remove-bridge-fdb-entry-for-the-auth.patch index 14db66876ac..92c46a815ed 100644 --- a/package/kernel/qca-ssdk/patches/0011-Revert-qca-ssdk-remove-bridge-fdb-entry-for-the-auth.patch +++ b/package/kernel/qca-ssdk/patches/0009-Revert-qca-ssdk-remove-bridge-fdb-entry-for-the-auth.patch @@ -1,7 +1,7 @@ -From c06e6edfb740d0ba0b804fa16d6222e257349089 Mon Sep 17 00:00:00 2001 +From 0582c76ce9c35ce8d49cba598e0e17073dd875b5 Mon Sep 17 00:00:00 2001 From: Alexandru Gagniuc Date: Fri, 23 Sep 2022 08:30:03 -0500 -Subject: [PATCH 11/11] Revert "qca-ssdk: remove bridge fdb entry for the +Subject: [PATCH 09/14] Revert "qca-ssdk: remove bridge fdb entry for the authentication failed mac" This change causes an undefined reference to "br_fdb_delete_by_netdev". diff --git a/package/kernel/qca-ssdk/patches/0012-qca-ssdk-Support-Linux-Style-Makefile-for-SSDK.patch b/package/kernel/qca-ssdk/patches/0010-Support-Linux-Style-Makefile-for-SSDK.patch similarity index 96% rename from package/kernel/qca-ssdk/patches/0012-qca-ssdk-Support-Linux-Style-Makefile-for-SSDK.patch rename to package/kernel/qca-ssdk/patches/0010-Support-Linux-Style-Makefile-for-SSDK.patch index 91b7d570d8a..180701bb143 100644 --- a/package/kernel/qca-ssdk/patches/0012-qca-ssdk-Support-Linux-Style-Makefile-for-SSDK.patch +++ b/package/kernel/qca-ssdk/patches/0010-Support-Linux-Style-Makefile-for-SSDK.patch @@ -1,7 +1,7 @@ -From edd3d4347cc73a99c7cf59aceeb1e8ad4d4dd303 Mon Sep 17 00:00:00 2001 +From 2276a0b93751f015ef719dedf9a0d4b55ae684d5 Mon Sep 17 00:00:00 2001 From: crao Date: Tue, 15 Nov 2022 18:50:01 +0800 -Subject: [PATCH] [qca-ssdk]: Support Linux-Style Makefile for SSDK +Subject: [PATCH 10/14] Support Linux-Style Makefile for SSDK Change-Id: I8c4399433b6422ef6192f70bf08b0d3023cc94b6 Signed-off-by: crao @@ -13,12 +13,7 @@ Signed-off-by: crao make/target.mk | 12 +++++++++++ src/api/Makefile | 2 +- 6 files changed, 77 insertions(+), 23 deletions(-) - mode change 100755 => 100644 Makefile create mode 100644 Makefile.modules - mode change 100755 => 100644 make/defs.mk - mode change 100755 => 100644 make/linux_opt.mk - mode change 100755 => 100644 make/target.mk - mode change 100755 => 100644 src/api/Makefile --- a/Makefile +++ b/Makefile diff --git a/package/kernel/qca-ssdk/patches/0013-qca-ssdk-fix-compilation-issue-in-Linux-Style-Makefi.patch b/package/kernel/qca-ssdk/patches/0011-fix-compilation-issue-in-Linux-Style-Makefile.patch similarity index 82% rename from package/kernel/qca-ssdk/patches/0013-qca-ssdk-fix-compilation-issue-in-Linux-Style-Makefi.patch rename to package/kernel/qca-ssdk/patches/0011-fix-compilation-issue-in-Linux-Style-Makefile.patch index 792cd9e31b5..f7d07a7baf9 100644 --- a/package/kernel/qca-ssdk/patches/0013-qca-ssdk-fix-compilation-issue-in-Linux-Style-Makefi.patch +++ b/package/kernel/qca-ssdk/patches/0011-fix-compilation-issue-in-Linux-Style-Makefile.patch @@ -1,14 +1,13 @@ -From 3026f89b06049df01d5fe19c5fccc972637aa344 Mon Sep 17 00:00:00 2001 +From 46a5dd73195081b5d78582f2a13f83e49f36e917 Mon Sep 17 00:00:00 2001 From: crao Date: Tue, 7 Mar 2023 17:15:07 +0800 -Subject: [PATCH] [qca-ssdk]: fix compilation issue in Linux-Style Makefile +Subject: [PATCH 11/14] fix compilation issue in Linux-Style Makefile Change-Id: If38251fc0a2bf4abc666d30f4812c0d9507310dc Signed-off-by: crao --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) - mode change 100644 => 100755 Makefile --- a/Makefile +++ b/Makefile diff --git a/package/kernel/qca-ssdk/patches/0014-qca-ssdk-fix-compilation-issue-in-Miami-yocto.patch b/package/kernel/qca-ssdk/patches/0012-fix-compilation-issue-in-Miami-yocto.patch similarity index 84% rename from package/kernel/qca-ssdk/patches/0014-qca-ssdk-fix-compilation-issue-in-Miami-yocto.patch rename to package/kernel/qca-ssdk/patches/0012-fix-compilation-issue-in-Miami-yocto.patch index 53c0c341316..7670d7f354a 100644 --- a/package/kernel/qca-ssdk/patches/0014-qca-ssdk-fix-compilation-issue-in-Miami-yocto.patch +++ b/package/kernel/qca-ssdk/patches/0012-fix-compilation-issue-in-Miami-yocto.patch @@ -1,7 +1,7 @@ -From 6e4efd68e6e560a1994bc273fe6f7a72139f3957 Mon Sep 17 00:00:00 2001 +From 0060aa1b0d2530672e64708d8062b3f33d007ed3 Mon Sep 17 00:00:00 2001 From: crao Date: Wed, 15 Mar 2023 11:19:39 +0800 -Subject: [PATCH] [qca-ssdk]: fix compilation issue in Miami yocto +Subject: [PATCH 12/14] fix compilation issue in Miami yocto Change-Id: I8526b9e43667d72ae9afa4ef8a13167088d194ba Signed-off-by: crao diff --git a/package/kernel/qca-ssdk/patches/0015-SSDK-config-add-kernel-6.1.patch b/package/kernel/qca-ssdk/patches/0013-SSDK-config-add-kernel-6.1.patch similarity index 68% rename from package/kernel/qca-ssdk/patches/0015-SSDK-config-add-kernel-6.1.patch rename to package/kernel/qca-ssdk/patches/0013-SSDK-config-add-kernel-6.1.patch index 77c54979a9c..44b5e625eed 100644 --- a/package/kernel/qca-ssdk/patches/0015-SSDK-config-add-kernel-6.1.patch +++ b/package/kernel/qca-ssdk/patches/0013-SSDK-config-add-kernel-6.1.patch @@ -1,7 +1,7 @@ -From 1f9eb43f118b86c0b68e9d82bfae77471d6c3921 Mon Sep 17 00:00:00 2001 +From 05aba6d6dfd49fe10b33cf221b7e81250a67033c Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Thu, 29 Sep 2022 09:59:20 +0200 -Subject: [PATCH] SSDK: config: add kernel 6.1 +Subject: [PATCH 13/14] SSDK: config: add kernel 6.1 Allow kernel 6.1 to be recognized and compiled under it. @@ -13,23 +13,23 @@ Signed-off-by: Robert Marko --- a/config +++ b/config -@@ -28,6 +28,10 @@ ifeq ($(KVER),$(filter 5.15%,$(KVER))) - OS_VER=5_15 +@@ -24,6 +24,10 @@ ifeq ($(KVER),$(filter 5.4%,$(KVER))) + OS_VER=5_4 endif +ifeq ($(KVER),$(filter 6.1%,$(KVER))) -+OS_VER=6_1 ++ OS_VER=6_1 +endif + ifeq ($(KVER), 3.4.0) OS_VER=3_4 endif -@@ -136,7 +140,7 @@ ifeq ($(ARCH), arm) +@@ -132,7 +136,7 @@ ifeq ($(ARCH), arm) endif ifeq ($(ARCH), arm64) -- ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4% 5.15%,$(KVER))) -+ ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4% 5.15% 6.1%,$(KVER))) +- ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4%,$(KVER))) ++ ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4% 6.1%,$(KVER))) CPU_CFLAG= -DMODULE -Os -pipe -march=armv8-a -mcpu=cortex-a53+crypto -fno-caller-saves -fno-strict-aliasing -fno-common -Wno-format-security -Wno-pointer-sign -Wno-unused-but-set-variable -Wno-error=unused-result -mcmodel=large endif endif @@ -39,8 +39,8 @@ Signed-off-by: Robert Marko KASAN_SHADOW_SCALE_SHIFT := 3 endif -- ifeq (5_4 5_15, $(OS_VER)) -+ ifeq (5_4 5_15 6_1, $(OS_VER)) +- ifeq (5_4, $(OS_VER)) ++ ifeq (5_4 6_1, $(OS_VER)) ifeq ($(ARCH), arm64) KASAN_OPTION += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT) endif @@ -48,8 +48,8 @@ Signed-off-by: Robert Marko endif -- ifeq ($(OS_VER),$(filter 4_4 5_4 5_15, $(OS_VER))) -+ ifeq ($(OS_VER),$(filter 4_4 5_4 5_15 6_1, $(OS_VER))) +- ifeq ($(OS_VER),$(filter 4_4 5_4, $(OS_VER))) ++ ifeq ($(OS_VER),$(filter 4_4 5_4 6_1, $(OS_VER))) MODULE_CFLAG += -DKVER34 MODULE_CFLAG += -DKVER32 MODULE_CFLAG += -DLNX26_22 diff --git a/package/kernel/qca-ssdk/patches/0016-SSDK-qca808x-use-get_random_u32.patch b/package/kernel/qca-ssdk/patches/0014-SSDK-qca808x-use-get_random_u32.patch similarity index 88% rename from package/kernel/qca-ssdk/patches/0016-SSDK-qca808x-use-get_random_u32.patch rename to package/kernel/qca-ssdk/patches/0014-SSDK-qca808x-use-get_random_u32.patch index d8cd89b7442..f5aa0e907c7 100644 --- a/package/kernel/qca-ssdk/patches/0016-SSDK-qca808x-use-get_random_u32.patch +++ b/package/kernel/qca-ssdk/patches/0014-SSDK-qca808x-use-get_random_u32.patch @@ -1,7 +1,7 @@ -From 55ea8c9b278aafe3211f7250986b1f9d9a06cd21 Mon Sep 17 00:00:00 2001 +From 6a49dd6bb2e40ce49351adb6100599f176d80494 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 21 Oct 2022 13:40:15 +0200 -Subject: [PATCH] SSDK: qca808x: use get_random_u32 +Subject: [PATCH 14/14] SSDK: qca808x: use get_random_u32 prandom has been removed from the kernel in 6.1-rc1, so use get_random_u32 instead as its the drop-in replacement. diff --git a/package/libs/openssl/Makefile b/package/libs/openssl/Makefile index a34a7849733..0d09114f06e 100644 --- a/package/libs/openssl/Makefile +++ b/package/libs/openssl/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=openssl PKG_VERSION:=3.0.9 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_BUILD_FLAGS:=no-mips16 gc-sections PKG_BUILD_PARALLEL:=1 @@ -366,6 +366,7 @@ define Build/Configure --libdir=lib \ --openssldir=/etc/ssl \ --cross-compile-prefix="$(TARGET_CROSS)" \ + $(TARGET_CFLAGS) \ $(TARGET_CPPFLAGS) \ $(TARGET_LDFLAGS) \ $(OPENSSL_OPTIONS) && \ diff --git a/package/libs/wolfssl/Makefile b/package/libs/wolfssl/Makefile index 260335c34f6..d9426d75fc3 100644 --- a/package/libs/wolfssl/Makefile +++ b/package/libs/wolfssl/Makefile @@ -100,8 +100,8 @@ This variant uses AES CPU instructions (Intel AESNI or ARMv8 Crypto Extension) endef define Package/libwolfsslcpu-crypto/config - if TARGET_armvirt && PACKAGE_libwolfsslcpu-crypto = y - comment "You are about to build libwolfsslcpu-crypto into an armvirt_64 image." + if TARGET_armsr && PACKAGE_libwolfsslcpu-crypto = y + comment "You are about to build libwolfsslcpu-crypto into an armsr_64 image." comment "Ensure all of your installation targets support the Crypto Extension. " comment "Look for the 'aes' feature in /proc/cpuinfo. This library does not do " comment "run-time detection and will crash if the CPU does not support it. " diff --git a/package/network/config/swconfig/src/cli.c b/package/network/config/swconfig/src/cli.c index eab6c64742e..2601f346db1 100644 --- a/package/network/config/swconfig/src/cli.c +++ b/package/network/config/swconfig/src/cli.c @@ -101,6 +101,24 @@ speed_str(int speed) return "unknown"; } +static void +free_attr_val(const struct switch_attr *attr, const struct switch_val *val) +{ + switch (attr->type) { + case SWITCH_TYPE_STRING: + free(val->value.s); + break; + case SWITCH_TYPE_PORTS: + free(val->value.ports); + break; + case SWITCH_TYPE_LINK: + free(val->value.link); + break; + default: + break; + } +} + static void print_attr_val(const struct switch_attr *attr, const struct switch_val *val) { @@ -150,8 +168,10 @@ show_attrs(struct switch_dev *dev, struct switch_attr *attr, struct switch_val * printf("\t%s: ", attr->name); if (swlib_get_attr(dev, attr, val) < 0) printf("???"); - else + else { print_attr_val(attr, val); + free_attr_val(attr, val); + } putchar('\n'); } attr = attr->next; @@ -354,6 +374,7 @@ int main(int argc, char **argv) goto out; } print_attr_val(a, &val); + free_attr_val(a, &val); putchar('\n'); break; case CMD_LOAD: diff --git a/package/network/services/ppp/Makefile b/package/network/services/ppp/Makefile index 80d5e46c348..40ec5c5cf12 100644 --- a/package/network/services/ppp/Makefile +++ b/package/network/services/ppp/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=ppp -PKG_RELEASE:=4 +PKG_RELEASE:=5 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/paulusmack/ppp diff --git a/package/network/services/ppp/patches/140-pppd-Fix-compilation-with-older-glibc-or-kernel-head.patch b/package/network/services/ppp/patches/140-pppd-Fix-compilation-with-older-glibc-or-kernel-head.patch new file mode 100644 index 00000000000..154ac7270bf --- /dev/null +++ b/package/network/services/ppp/patches/140-pppd-Fix-compilation-with-older-glibc-or-kernel-head.patch @@ -0,0 +1,54 @@ +From 98ec18f098e5ef68e3a8cc6954fcaf5a7fb8b7be Mon Sep 17 00:00:00 2001 +From: pali <7141871+pali@users.noreply.github.com> +Date: Mon, 15 Feb 2021 07:54:01 +0100 +Subject: [PATCH] pppd: Fix compilation with older glibc or kernel headers + (#248) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +glibc versions prior to 2.24 do not define SOL_NETLINK and linux kernel +versions prior to 4.3 do not define NETLINK_CAP_ACK. So add fallback +definitions for these macros into pppd/sys-linux.c file. + +Also extend description why we call SOL_NETLINK/NETLINK_CAP_ACK option. + +Signed-off-by: Pali Rohár +--- + pppd/sys-linux.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +--- a/pppd/sys-linux.c ++++ b/pppd/sys-linux.c +@@ -125,6 +125,14 @@ + #include + #include + #include ++/* glibc versions prior to 2.24 do not define SOL_NETLINK */ ++#ifndef SOL_NETLINK ++#define SOL_NETLINK 270 ++#endif ++/* linux kernel versions prior to 4.3 do not define/support NETLINK_CAP_ACK */ ++#ifndef NETLINK_CAP_ACK ++#define NETLINK_CAP_ACK 10 ++#endif + #endif + + #include "pppd.h" +@@ -2843,7 +2851,15 @@ static int append_peer_ipv6_address(unsi + if (fd < 0) + return 0; + +- /* do not ask for error message content */ ++ /* ++ * Tell kernel to not send to us payload of acknowledgment error message. ++ * NETLINK_CAP_ACK option is supported since Linux kernel version 4.3 and ++ * older kernel versions always send full payload in acknowledgment netlink ++ * message. We ignore payload of this message as we need only error code, ++ * to check if our set remote peer address request succeeded or failed. ++ * So ignore return value from the following setsockopt() call as setting ++ * option NETLINK_CAP_ACK means for us just a kernel hint / optimization. ++ */ + one = 1; + setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one)); + diff --git a/package/network/services/ppp/patches/141-Expand-byte-count-statistics-to-64-bits-298.patch b/package/network/services/ppp/patches/141-Expand-byte-count-statistics-to-64-bits-298.patch new file mode 100644 index 00000000000..e4de5c0aa21 --- /dev/null +++ b/package/network/services/ppp/patches/141-Expand-byte-count-statistics-to-64-bits-298.patch @@ -0,0 +1,518 @@ +From 81ad945630120cc1c27c8bb00503be42b76ff202 Mon Sep 17 00:00:00 2001 +From: Jaco Kroon +Date: Thu, 13 Jan 2022 08:38:04 +0200 +Subject: [PATCH] Expand byte count statistics to 64 bits (#298) + +* Add Gigawords to radius packets where applicable. + +IMPORTANT NOTE: The ioctl() only supports 32-bit counters. In order t +obtain 64-bit counters, these are now pulled in from sysfs (it's assumed +to be mounted on /sys which I'm assuming is standard). + +It is unknown whether sysfs will be available everywhere, as such, keep +the ioctl() method in place, but attempt to detect wrap-overs. + +If the sysfs mechanism fails, fail back to the ioctl(). + +Given maximum data rates, the intervals between calling this needs to be +such that no more than 4GB (2^32) bytes are sent or received in any +given interval. Mostly important for radius plugin where data +accounting may be in effect. + +Towards this, a timer interval on 25 seconds is set to force a ioctl() +poll irrespective of the rate of stats update calls. This may be +important for especially radius that needs to provide interim-update +intervals, if the interim updates is too long and the counters could +wrap-over twice in a single interval. At 25 seconds we should detect +all wraps up to an effective data rate of 1.37Gbps, which for my +purposes is adequate. + +Possible downsides, 4 files are opened, read and closed every time +statistics is requested. This results in 12 system calls every single +time statistics is required, compared to 1 for the ioctl. Efficiency is +unknown, but as a rule of thumb fewer system calls are better, this is +however not a critical path in my opinion, so should not be a problem. +If required I can run a few benchmarks using gettimeofday() to measure +actual impact. + +Signed-off-by: Jaco Kroon + +* Use netlink if possible to obtain 64-bit stats. + +This uses two system calls per round. + +This should be preferred where available. It seems the RTM_GETSTATS was +only added from 2016 some point (4.7.0 as per pali), which is in my +opinion old, but given experience with certain embedded systems does +need to be supported. + +Signed-off-by: Jaco Kroon + +Co-authored-by: Jaco Kroon +--- + pppd/main.c | 5 +- + pppd/plugins/radius/etc/dictionary | 2 + + pppd/plugins/radius/radius.c | 28 ++- + pppd/plugins/radius/radiusclient.h | 2 + + pppd/pppd.h | 9 +- + pppd/sys-linux.c | 281 ++++++++++++++++++++++++++++- + 6 files changed, 313 insertions(+), 14 deletions(-) + +--- a/pppd/main.c ++++ b/pppd/main.c +@@ -87,6 +87,7 @@ + #include + #include + #include ++#include + + #include "pppd.h" + #include "magic.h" +@@ -1230,9 +1231,9 @@ update_link_stats(int u) + + slprintf(numbuf, sizeof(numbuf), "%u", link_connect_time); + script_setenv("CONNECT_TIME", numbuf, 0); +- slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_out); ++ snprintf(numbuf, sizeof(numbuf), "%" PRIu64, link_stats.bytes_out); + script_setenv("BYTES_SENT", numbuf, 0); +- slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_in); ++ snprintf(numbuf, sizeof(numbuf), "%" PRIu64, link_stats.bytes_in); + script_setenv("BYTES_RCVD", numbuf, 0); + } + +--- a/pppd/plugins/radius/etc/dictionary ++++ b/pppd/plugins/radius/etc/dictionary +@@ -82,6 +82,8 @@ ATTRIBUTE Acct-Session-Time 46 integer + ATTRIBUTE Acct-Input-Packets 47 integer + ATTRIBUTE Acct-Output-Packets 48 integer + ATTRIBUTE Acct-Terminate-Cause 49 integer ++ATTRIBUTE Acct-Input-Gigawords 52 integer ++ATTRIBUTE Acct-Output-Gigawords 53 integer + ATTRIBUTE Chap-Challenge 60 string + ATTRIBUTE NAS-Port-Type 61 integer + ATTRIBUTE Port-Limit 62 integer +--- a/pppd/plugins/radius/radius.c ++++ b/pppd/plugins/radius/radius.c +@@ -1020,12 +1020,22 @@ radius_acct_stop(void) + av_type = link_connect_time; + rc_avpair_add(&send, PW_ACCT_SESSION_TIME, &av_type, 0, VENDOR_NONE); + +- av_type = link_stats.bytes_out; ++ av_type = link_stats.bytes_out & 0xFFFFFFFF; + rc_avpair_add(&send, PW_ACCT_OUTPUT_OCTETS, &av_type, 0, VENDOR_NONE); + +- av_type = link_stats.bytes_in; ++ if (link_stats.bytes_out > 0xFFFFFFFF) { ++ av_type = link_stats.bytes_out >> 32; ++ rc_avpair_add(&send, PW_ACCT_OUTPUT_GIGAWORDS, &av_type, 0, VENDOR_NONE); ++ } ++ ++ av_type = link_stats.bytes_in & 0xFFFFFFFF; + rc_avpair_add(&send, PW_ACCT_INPUT_OCTETS, &av_type, 0, VENDOR_NONE); + ++ if (link_stats.bytes_in > 0xFFFFFFFF) { ++ av_type = link_stats.bytes_in >> 32; ++ rc_avpair_add(&send, PW_ACCT_INPUT_GIGAWORDS, &av_type, 0, VENDOR_NONE); ++ } ++ + av_type = link_stats.pkts_out; + rc_avpair_add(&send, PW_ACCT_OUTPUT_PACKETS, &av_type, 0, VENDOR_NONE); + +@@ -1172,12 +1182,22 @@ radius_acct_interim(void *ignored) + av_type = link_connect_time; + rc_avpair_add(&send, PW_ACCT_SESSION_TIME, &av_type, 0, VENDOR_NONE); + +- av_type = link_stats.bytes_out; ++ av_type = link_stats.bytes_out & 0xFFFFFFFF; + rc_avpair_add(&send, PW_ACCT_OUTPUT_OCTETS, &av_type, 0, VENDOR_NONE); + +- av_type = link_stats.bytes_in; ++ if (link_stats.bytes_out > 0xFFFFFFFF) { ++ av_type = link_stats.bytes_out >> 32; ++ rc_avpair_add(&send, PW_ACCT_OUTPUT_GIGAWORDS, &av_type, 0, VENDOR_NONE); ++ } ++ ++ av_type = link_stats.bytes_in & 0xFFFFFFFF; + rc_avpair_add(&send, PW_ACCT_INPUT_OCTETS, &av_type, 0, VENDOR_NONE); + ++ if (link_stats.bytes_in > 0xFFFFFFFF) { ++ av_type = link_stats.bytes_in >> 32; ++ rc_avpair_add(&send, PW_ACCT_INPUT_GIGAWORDS, &av_type, 0, VENDOR_NONE); ++ } ++ + av_type = link_stats.pkts_out; + rc_avpair_add(&send, PW_ACCT_OUTPUT_PACKETS, &av_type, 0, VENDOR_NONE); + +--- a/pppd/plugins/radius/radiusclient.h ++++ b/pppd/plugins/radius/radiusclient.h +@@ -184,6 +184,8 @@ typedef struct pw_auth_hdr + #define PW_ACCT_LINK_COUNT 51 /* integer */ + + /* From RFC 2869 */ ++#define PW_ACCT_INPUT_GIGAWORDS 52 /* integer */ ++#define PW_ACCT_OUTPUT_GIGAWORDS 53 /* integer */ + #define PW_ACCT_INTERIM_INTERVAL 85 /* integer */ + + /* Merit Experimental Extensions */ +--- a/pppd/pppd.h ++++ b/pppd/pppd.h +@@ -53,6 +53,7 @@ + #include /* for encrypt */ + #include /* for setkey */ + #include ++#include + #include /* for NGROUPS_MAX */ + #include /* for MAXPATHLEN and BSD4_4, if defined */ + #include /* for u_int32_t, if defined */ +@@ -173,8 +174,8 @@ struct permitted_ip { + * pppd needs. + */ + struct pppd_stats { +- unsigned int bytes_in; +- unsigned int bytes_out; ++ uint64_t bytes_in; ++ uint64_t bytes_out; + unsigned int pkts_in; + unsigned int pkts_out; + }; +@@ -347,7 +348,7 @@ extern char *max_tls_version; + extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ + extern int maxoctets_dir; /* Direction : + 0 - in+out (default) +- 1 - in ++ 1 - in + 2 - out + 3 - max(in,out) */ + extern int maxoctets_timeout; /* Timeout for check of octets limit */ +@@ -356,7 +357,7 @@ extern int maxoctets_timeout; /* + #define PPP_OCTETS_DIRECTION_OUT 2 + #define PPP_OCTETS_DIRECTION_MAXOVERAL 3 + /* same as previos, but little different on RADIUS side */ +-#define PPP_OCTETS_DIRECTION_MAXSESSION 4 ++#define PPP_OCTETS_DIRECTION_MAXSESSION 4 + #endif + + #ifdef PPP_FILTER +--- a/pppd/sys-linux.c ++++ b/pppd/sys-linux.c +@@ -79,6 +79,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -92,6 +93,7 @@ + #include + #include + #include ++#include + + /* This is in netdevice.h. However, this compile will fail miserably if + you attempt to include netdevice.h because it has so many references +@@ -121,9 +123,19 @@ + #include + #include + +-#ifdef INET6 + #include + #include ++#include ++/* Attempt at retaining compile-support with older than 4.7 kernels, or kernels ++ * where RTM_NEWSTATS isn't defined for whatever reason. ++ */ ++#ifndef RTM_NEWSTATS ++#define RTM_NEWSTATS 92 ++#define RTM_GETSTATS 94 ++#define IFLA_STATS_LINK_64 1 ++#endif ++ ++#ifdef INET6 + #include + /* glibc versions prior to 2.24 do not define SOL_NETLINK */ + #ifndef SOL_NETLINK +@@ -1407,11 +1419,17 @@ get_idle_time(int u, struct ppp_idle *ip + + /******************************************************************** + * +- * get_ppp_stats - return statistics for the link. ++ * get_ppp_stats_iocl - return statistics for the link, using the ioctl() method, ++ * this only supports 32-bit counters, so need to count the wraps. + */ +-int +-get_ppp_stats(int u, struct pppd_stats *stats) ++static int ++get_ppp_stats_ioctl(int u, struct pppd_stats *stats) + { ++ static u_int32_t previbytes = 0; ++ static u_int32_t prevobytes = 0; ++ static u_int32_t iwraps = 0; ++ static u_int32_t owraps = 0; ++ + struct ifpppstatsreq req; + + memset (&req, 0, sizeof (req)); +@@ -1426,7 +1444,262 @@ get_ppp_stats(int u, struct pppd_stats * + stats->bytes_out = req.stats.p.ppp_obytes; + stats->pkts_in = req.stats.p.ppp_ipackets; + stats->pkts_out = req.stats.p.ppp_opackets; ++ ++ if (stats->bytes_in < previbytes) ++ ++iwraps; ++ if (stats->bytes_out < prevobytes) ++ ++owraps; ++ ++ previbytes = stats->bytes_in; ++ prevobytes = stats->bytes_out; ++ ++ stats->bytes_in += (uint64_t)iwraps << 32; ++ stats->bytes_out += (uint64_t)owraps << 32; ++ ++ return 1; ++} ++ ++/******************************************************************** ++ * get_ppp_stats_rtnetlink - return statistics for the link, using rtnetlink ++ * This provides native 64-bit counters. ++ */ ++static int ++get_ppp_stats_rtnetlink(int u, struct pppd_stats *stats) ++{ ++ static int rtnl_fd = -1; ++ ++ struct sockaddr_nl nladdr; ++ struct { ++ struct nlmsghdr nlh; ++ struct if_stats_msg ifsm; ++ } nlreq; ++ struct nlresp { ++ struct nlmsghdr nlh; ++ union { ++ struct { ++ struct nlmsgerr nlerr; ++ char __end_err[0]; ++ }; ++ struct { ++ struct rtmsg rth; ++ struct { ++ /* We only case about these first fields from rtnl_link_stats64 */ ++ uint64_t rx_packets; ++ uint64_t tx_packets; ++ uint64_t rx_bytes; ++ uint64_t tx_bytes; ++ } stats; ++ char __end_stats[0]; ++ }; ++ }; ++ } nlresp; ++ ssize_t nlresplen; ++ struct iovec iov; ++ struct msghdr msg; ++ ++ memset(&nladdr, 0, sizeof(nladdr)); ++ nladdr.nl_family = AF_NETLINK; ++ ++ if (rtnl_fd < 0) { ++ rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); ++ if (rtnl_fd < 0) { ++ error("get_ppp_stats_rtnetlink: error creating NETLINK socket: %m (line %d)", __LINE__); ++ return 0; ++ } ++ ++ if (bind(rtnl_fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) { ++ error("get_ppp_stats_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__); ++ goto err; ++ } ++ } ++ ++ memset(&nlreq, 0, sizeof(nlreq)); ++ nlreq.nlh.nlmsg_len = sizeof(nlreq); ++ nlreq.nlh.nlmsg_type = RTM_GETSTATS; ++ nlreq.nlh.nlmsg_flags = NLM_F_REQUEST; ++ ++ nlreq.ifsm.ifindex = if_nametoindex(ifname); ++ nlreq.ifsm.filter_mask = IFLA_STATS_LINK_64; ++ ++ memset(&iov, 0, sizeof(iov)); ++ iov.iov_base = &nlreq; ++ iov.iov_len = sizeof(nlreq); ++ ++ memset(&msg, 0, sizeof(msg)); ++ msg.msg_name = &nladdr; ++ msg.msg_namelen = sizeof(nladdr); ++ msg.msg_iov = &iov; ++ msg.msg_iovlen = 1; ++ ++ if (sendmsg(rtnl_fd, &msg, 0) < 0) { ++ error("get_ppp_stats_rtnetlink: sendmsg(RTM_GETSTATS): %m (line %d)", __LINE__); ++ goto err; ++ } ++ ++ /* We just need to repoint to IOV ... everything else stays the same */ ++ iov.iov_base = &nlresp; ++ iov.iov_len = sizeof(nlresp); ++ ++ nlresplen = recvmsg(rtnl_fd, &msg, 0); ++ ++ if (nlresplen < 0) { ++ error("get_ppp_stats_rtnetlink: recvmsg(RTM_GETSTATS): %m (line %d)", __LINE__); ++ goto err; ++ } ++ ++ if (nlresplen < sizeof(nlresp.nlh)) { ++ error("get_ppp_stats_rtnetlink: Netlink response message was incomplete (line %d)", __LINE__); ++ goto err; ++ } ++ ++ if (nlresp.nlh.nlmsg_type == NLMSG_ERROR) { ++ if (nlresplen < offsetof(struct nlresp, __end_err)) { ++ if (kernel_version >= KVERSION(4,7,0)) ++ error("get_ppp_stats_rtnetlink: Netlink responded with error: %s (line %d)", strerror(-nlresp.nlerr.error), __LINE__); ++ } else { ++ error("get_ppp_stats_rtnetlink: Netlink responded with an error message, but the nlmsgerr structure is incomplete (line %d).", ++ __LINE__); ++ } ++ goto err; ++ } ++ ++ if (nlresp.nlh.nlmsg_type != RTM_NEWSTATS) { ++ error("get_ppp_stats_rtnetlink: Expected RTM_NEWSTATS response, found something else (mlmsg_type %d, line %d)", ++ nlresp.nlh.nlmsg_type, __LINE__); ++ goto err; ++ } ++ ++ if (nlresplen < offsetof(struct nlresp, __end_stats)) { ++ error("get_ppp_stats_rtnetlink: Obtained an insufficiently sized rtnl_link_stats64 struct from the kernel (line %d).", __LINE__); ++ goto err; ++ } ++ ++ stats->bytes_in = nlresp.stats.rx_bytes; ++ stats->bytes_out = nlresp.stats.tx_bytes; ++ stats->pkts_in = nlresp.stats.rx_packets; ++ stats->pkts_out = nlresp.stats.tx_packets; ++ + return 1; ++err: ++ close(rtnl_fd); ++ rtnl_fd = -1; ++ return 0; ++} ++ ++/******************************************************************** ++ * get_ppp_stats_sysfs - return statistics for the link, using the files in sysfs, ++ * this provides native 64-bit counters. ++ */ ++static int ++get_ppp_stats_sysfs(int u, struct pppd_stats *stats) ++{ ++ char fname[PATH_MAX+1]; ++ char buf[21], *err; /* 2^64 < 10^20 */ ++ int blen, fd, rlen; ++ unsigned long long val; ++ ++ struct { ++ const char* fname; ++ void* ptr; ++ unsigned size; ++ } slist[] = { ++#define statfield(fn, field) { .fname = #fn, .ptr = &stats->field, .size = sizeof(stats->field) } ++ statfield(rx_bytes, bytes_in), ++ statfield(tx_bytes, bytes_out), ++ statfield(rx_packets, pkts_in), ++ statfield(tx_packets, pkts_out), ++#undef statfield ++ }; ++ ++ blen = snprintf(fname, sizeof(fname), "/sys/class/net/%s/statistics/", ifname); ++ if (blen >= sizeof(fname)) ++ return 0; /* ifname max 15, so this should be impossible */ ++ ++ for (int i = 0; i < sizeof(slist) / sizeof(*slist); ++i) { ++ if (snprintf(fname + blen, sizeof(fname) - blen, "%s", slist[i].fname) >= sizeof(fname) - blen) { ++ fname[blen] = 0; ++ error("sysfs stats: filename %s/%s overflowed PATH_MAX", fname, slist[i].fname); ++ return 0; ++ } ++ ++ fd = open(fname, O_RDONLY); ++ if (fd < 0) { ++ error("%s: %m", fname); ++ return 0; ++ } ++ ++ rlen = read(fd, buf, sizeof(buf) - 1); ++ close(fd); ++ if (rlen < 0) { ++ error("%s: %m", fname); ++ return 0; ++ } ++ /* trim trailing \n if present */ ++ while (rlen > 0 && buf[rlen-1] == '\n') ++ rlen--; ++ buf[rlen] = 0; ++ ++ errno = 0; ++ val = strtoull(buf, &err, 10); ++ if (*buf < '0' || *buf > '9' || errno != 0 || *err) { ++ error("string to number conversion error converting %s (from %s) for remaining string %s%s%s", ++ buf, fname, err, errno ? ": " : "", errno ? strerror(errno) : ""); ++ return 0; ++ } ++ switch (slist[i].size) { ++#define stattype(type) case sizeof(type): *(type*)slist[i].ptr = (type)val; break ++ stattype(uint64_t); ++ stattype(uint32_t); ++ stattype(uint16_t); ++ stattype(uint8_t); ++#undef stattype ++ default: ++ error("Don't know how to store stats for %s of size %u", slist[i].fname, slist[i].size); ++ return 0; ++ } ++ } ++ ++ return 1; ++} ++ ++/******************************************************************** ++ * Periodic timer function to be used to keep stats up to date in case of ioctl ++ * polling. ++ * ++ * Given the 25s interval this should be fine up to data rates of 1.37Gbps. ++ * If you do change the timer, remember to also bring the get_ppp_stats (which ++ * sets up the initial trigger) as well. ++ */ ++static void ++ppp_stats_poller(void* u) ++{ ++ struct pppd_stats dummy; ++ get_ppp_stats_ioctl((long)u, &dummy); ++ TIMEOUT(ppp_stats_poller, u, 25); ++} ++ ++/******************************************************************** ++ * get_ppp_stats - return statistics for the link. ++ */ ++int get_ppp_stats(int u, struct pppd_stats *stats) ++{ ++ static int (*func)(int, struct pppd_stats*) = NULL; ++ ++ if (!func) { ++ if (get_ppp_stats_rtnetlink(u, stats)) { ++ func = get_ppp_stats_rtnetlink; ++ return 1; ++ } ++ if (get_ppp_stats_sysfs(u, stats)) { ++ func = get_ppp_stats_sysfs; ++ return 1; ++ } ++ warn("statistics falling back to ioctl which only supports 32-bit counters"); ++ func = get_ppp_stats_ioctl; ++ TIMEOUT(ppp_stats_poller, (void*)(long)u, 25); ++ } ++ ++ return func(u, stats); + } + + /******************************************************************** diff --git a/package/network/services/ppp/patches/142-pppd-Add-support-for-registering-ppp-interface-via-L.patch b/package/network/services/ppp/patches/142-pppd-Add-support-for-registering-ppp-interface-via-L.patch new file mode 100644 index 00000000000..9987d3dce9d --- /dev/null +++ b/package/network/services/ppp/patches/142-pppd-Add-support-for-registering-ppp-interface-via-L.patch @@ -0,0 +1,299 @@ +From 4a54e34cf5629f9fed61f0b7d69ee3ba4d874bc6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Sat, 9 Jul 2022 13:40:24 +0200 +Subject: [PATCH] pppd: Add support for registering ppp interface via Linux + rtnetlink API +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +pppd currently creates ppp network interface via PPPIOCNEWUNIT ioctl API. +This API creates a new ppp network interface named "ppp". If user +supply option "ifname" with custom network name then pppd calls SIOCSIFNAME +ioctl to rename "ppp" to custom name immediately after successful +PPPIOCNEWUNIT ioctl call. If custom name is already registered then +SIOCSIFNAME ioctl fails and pppd close current channel (which destroy also +network interface). + +This has side effect that in the first few miliseconds interface has +different name as what user supplied. + +Tools like systemd, udev or NetworkManager are trying to query +interface attributes based on interface name immediately when new +network interface is created. + +But if interface is renamed immediately after creation then these tools +fails. For example when running pppd with option "ifname ppp-wan" following +error is reported by systemd / udev into dmesg log: + + [ 35.718732] PPP generic driver version 2.4.2 + [ 35.793914] NET: Registered protocol family 24 + [ 35.889924] systemd-udevd[1852]: link_config: autonegotiation is unset or enabled, the speed and duplex are not writable. + [ 35.901450] ppp-wan: renamed from ppp0 + [ 35.930332] systemd-udevd[1852]: link_config: could not get ethtool features for ppp0 + [ 35.939473] systemd-udevd[1852]: Could not set offload features of ppp0: No such device + +There is an easy way to fix this issue: Use new rtnetlink API. + +Via rtnetlink API it is possible to create ppp network interface with +custom ifname atomically. Just it is not possible to specify custom ppp +unit id. + +So use new rtnetlink API when user requested custom ifname without custom +ppp unit id. This will avoid system issues with interface renaming as ppp +interface is directly registered with specified final name. + +This has also advantage that if requested interface name already exists +then pppd fail during registering of networking interface and not during +renaming network interface which happens after successful registration. + +If user supply custom ppp unit id then it is required to use old ioctl API +as currently it is the only API which allows specifying ppp unit id. + +When user does not specify custom ifname stay also with old ioctl API. +There is currently a bug in kernel which cause that when empty interface is +specified in rtnetlink message for creating ppp interface then kernel +creates ppp interface but with pseudo-random name, not derived from ppp +unit id. And therefore it is not possible to retrieve what is the name of +newly created network interface. So when user does not specify interface +name via "ifname" option (which means that want from kernel to choose some +"free" interface name) it is needed to use old ioctl API which do it +correctly for now. + +Signed-off-by: Pali Rohár +--- + pppd/sys-linux.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 192 insertions(+), 2 deletions(-) + +--- a/pppd/sys-linux.c ++++ b/pppd/sys-linux.c +@@ -126,6 +126,11 @@ + #include + #include + #include ++ ++#ifdef INET6 ++#include ++#endif ++ + /* Attempt at retaining compile-support with older than 4.7 kernels, or kernels + * where RTM_NEWSTATS isn't defined for whatever reason. + */ +@@ -135,16 +140,20 @@ + #define IFLA_STATS_LINK_64 1 + #endif + +-#ifdef INET6 +-#include + /* glibc versions prior to 2.24 do not define SOL_NETLINK */ + #ifndef SOL_NETLINK + #define SOL_NETLINK 270 + #endif ++ + /* linux kernel versions prior to 4.3 do not define/support NETLINK_CAP_ACK */ + #ifndef NETLINK_CAP_ACK + #define NETLINK_CAP_ACK 10 + #endif ++ ++/* linux kernel versions prior to 4.7 do not define/support IFLA_PPP_DEV_FD */ ++#ifndef IFLA_PPP_MAX ++/* IFLA_PPP_DEV_FD is declared as enum when IFLA_PPP_MAX is defined */ ++#define IFLA_PPP_DEV_FD 1 + #endif + + #include "pppd.h" +@@ -657,6 +666,160 @@ void generic_disestablish_ppp(int dev_fd + } + + /* ++ * make_ppp_unit_rtnetlink - register a new ppp network interface for ppp_dev_fd ++ * with specified req_ifname via rtnetlink. Interface name req_ifname must not ++ * be empty. Custom ppp unit id req_unit is ignored and kernel choose some free. ++ */ ++static int make_ppp_unit_rtnetlink(void) ++{ ++ struct { ++ struct nlmsghdr nlh; ++ struct ifinfomsg ifm; ++ struct { ++ struct rtattr rta; ++ char ifname[IFNAMSIZ]; ++ } ifn; ++ struct { ++ struct rtattr rta; ++ struct { ++ struct rtattr rta; ++ char ifkind[sizeof("ppp")]; ++ } ifik; ++ struct { ++ struct rtattr rta; ++ struct { ++ struct rtattr rta; ++ union { ++ int ppp_dev_fd; ++ } ppp; ++ } ifdata[1]; ++ } ifid; ++ } ifli; ++ } nlreq; ++ struct { ++ struct nlmsghdr nlh; ++ struct nlmsgerr nlerr; ++ } nlresp; ++ struct sockaddr_nl nladdr; ++ struct iovec iov; ++ struct msghdr msg; ++ ssize_t nlresplen; ++ int one; ++ int fd; ++ ++ fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); ++ if (fd < 0) { ++ error("make_ppp_unit_rtnetlink: socket(NETLINK_ROUTE): %m (line %d)", __LINE__); ++ return 0; ++ } ++ ++ /* Tell kernel to not send to us payload of acknowledgment error message. */ ++ one = 1; ++ setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one)); ++ ++ memset(&nladdr, 0, sizeof(nladdr)); ++ nladdr.nl_family = AF_NETLINK; ++ ++ if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) { ++ error("make_ppp_unit_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__); ++ close(fd); ++ return 0; ++ } ++ ++ memset(&nlreq, 0, sizeof(nlreq)); ++ nlreq.nlh.nlmsg_len = sizeof(nlreq); ++ nlreq.nlh.nlmsg_type = RTM_NEWLINK; ++ nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE; ++ nlreq.ifm.ifi_family = AF_UNSPEC; ++ nlreq.ifm.ifi_type = ARPHRD_NETROM; ++ nlreq.ifn.rta.rta_len = sizeof(nlreq.ifn); ++ nlreq.ifn.rta.rta_type = IFLA_IFNAME; ++ strlcpy(nlreq.ifn.ifname, req_ifname, sizeof(nlreq.ifn.ifname)); ++ nlreq.ifli.rta.rta_len = sizeof(nlreq.ifli); ++ nlreq.ifli.rta.rta_type = IFLA_LINKINFO; ++ nlreq.ifli.ifik.rta.rta_len = sizeof(nlreq.ifli.ifik); ++ nlreq.ifli.ifik.rta.rta_type = IFLA_INFO_KIND; ++ strcpy(nlreq.ifli.ifik.ifkind, "ppp"); ++ nlreq.ifli.ifid.rta.rta_len = sizeof(nlreq.ifli.ifid); ++ nlreq.ifli.ifid.rta.rta_type = IFLA_INFO_DATA; ++ nlreq.ifli.ifid.ifdata[0].rta.rta_len = sizeof(nlreq.ifli.ifid.ifdata[0]); ++ nlreq.ifli.ifid.ifdata[0].rta.rta_type = IFLA_PPP_DEV_FD; ++ nlreq.ifli.ifid.ifdata[0].ppp.ppp_dev_fd = ppp_dev_fd; ++ ++ memset(&nladdr, 0, sizeof(nladdr)); ++ nladdr.nl_family = AF_NETLINK; ++ ++ memset(&iov, 0, sizeof(iov)); ++ iov.iov_base = &nlreq; ++ iov.iov_len = sizeof(nlreq); ++ ++ memset(&msg, 0, sizeof(msg)); ++ msg.msg_name = &nladdr; ++ msg.msg_namelen = sizeof(nladdr); ++ msg.msg_iov = &iov; ++ msg.msg_iovlen = 1; ++ ++ if (sendmsg(fd, &msg, 0) < 0) { ++ error("make_ppp_unit_rtnetlink: sendmsg(RTM_NEWLINK/NLM_F_CREATE): %m (line %d)", __LINE__); ++ close(fd); ++ return 0; ++ } ++ ++ memset(&iov, 0, sizeof(iov)); ++ iov.iov_base = &nlresp; ++ iov.iov_len = sizeof(nlresp); ++ ++ memset(&msg, 0, sizeof(msg)); ++ msg.msg_name = &nladdr; ++ msg.msg_namelen = sizeof(nladdr); ++ msg.msg_iov = &iov; ++ msg.msg_iovlen = 1; ++ ++ nlresplen = recvmsg(fd, &msg, 0); ++ ++ if (nlresplen < 0) { ++ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): %m (line %d)", __LINE__); ++ close(fd); ++ return 0; ++ } ++ ++ close(fd); ++ ++ if (nladdr.nl_family != AF_NETLINK) { ++ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not a netlink packet (line %d)", __LINE__); ++ return 0; ++ } ++ ++ if ((size_t)nlresplen < sizeof(nlresp) || nlresp.nlh.nlmsg_len < sizeof(nlresp)) { ++ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Acknowledgment netlink packet too short (line %d)", __LINE__); ++ return 0; ++ } ++ ++ /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */ ++ if (nlresp.nlh.nlmsg_type != NLMSG_ERROR) { ++ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not an acknowledgment netlink packet (line %d)", __LINE__); ++ return 0; ++ } ++ ++ /* error == 0 indicates success, negative value is errno code */ ++ if (nlresp.nlerr.error != 0) { ++ /* ++ * Linux kernel versions prior to 4.7 do not support creating ppp ++ * interfaces via rtnetlink API and therefore error response is ++ * expected. On older kernel versions do not show this error message. ++ * When error is different than EEXIST then pppd tries to fallback to ++ * the old ioctl method. ++ */ ++ errno = (nlresp.nlerr.error < 0) ? -nlresp.nlerr.error : EINVAL; ++ if (kernel_version >= KVERSION(4,7,0)) ++ error("Couldn't create ppp interface %s: %m", req_ifname); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++/* + * make_ppp_unit - make a new ppp unit for ppp_dev_fd. + * Assumes new_style_driver. + */ +@@ -676,6 +839,33 @@ static int make_ppp_unit(void) + || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1) + warn("Couldn't set /dev/ppp to nonblock: %m"); + ++ /* ++ * Via rtnetlink it is possible to create ppp network interface with ++ * custom ifname atomically. But it is not possible to specify custom ++ * ppp unit id. ++ * ++ * Tools like systemd, udev or NetworkManager are trying to query ++ * interface attributes based on interface name immediately when new ++ * network interface is created. And therefore immediate interface ++ * renaming is causing issues. ++ * ++ * So use rtnetlink API only when user requested custom ifname. It will ++ * avoid system issues with interface renaming. ++ */ ++ if (req_unit == -1 && req_ifname[0] != '\0' && kernel_version >= KVERSION(2,1,16)) { ++ if (make_ppp_unit_rtnetlink()) { ++ if (ioctl(ppp_dev_fd, PPPIOCGUNIT, &ifunit)) ++ fatal("Couldn't retrieve PPP unit id: %m"); ++ return 0; ++ } ++ /* ++ * If interface with requested name already exist return error ++ * otherwise fallback to old ioctl method. ++ */ ++ if (errno == EEXIST) ++ return -1; ++ } ++ + ifunit = req_unit; + x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); + if (x < 0 && req_unit >= 0 && errno == EEXIST) { diff --git a/package/network/services/ppp/patches/143-pppd-Workaround-for-generating-ppp-unit-id-on-Linux-.patch b/package/network/services/ppp/patches/143-pppd-Workaround-for-generating-ppp-unit-id-on-Linux-.patch new file mode 100644 index 00000000000..abe559e0748 --- /dev/null +++ b/package/network/services/ppp/patches/143-pppd-Workaround-for-generating-ppp-unit-id-on-Linux-.patch @@ -0,0 +1,59 @@ +From 44609bfc974bdafc0316d069aabf5e2903efa805 Mon Sep 17 00:00:00 2001 +From: pali <7141871+pali@users.noreply.github.com> +Date: Tue, 9 Aug 2022 11:20:15 +0200 +Subject: [PATCH] pppd: Workaround for generating ppp unit id on Linux (#355) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Linux kernel has nasty bug / feature. If PPPIOCNEWUNIT is called with +negative ppp unit id (which is default option when command line argument +"unit" is not specified; and tells kernel to choose some free ppp unit id) +and the lowest unused/free ppp unit id is present in some existing network +interface name prefixed by "ppp" string then this PPPIOCNEWUNIT ioctl +fails. In this case kernel is basically unable to create a new ppp +interface via PPPIOCNEWUNIT ioctl when user does not specify some unused +and non-conflicted unit id. + +Linux kernel should be fixed to choose usable ppp unit id when was +requested via PPPIOCNEWUNIT parameter -1. + +Until this happens, add a workaround for pppd to help choosing some random +ppp unit id when kernel returns this error. + +Simple test case (run on system when there is no ppp interface): + + sudo ./pppd ifname ppp1 nodefaultroute noauth nolock local nodetach pty "./pppd nodefaultroute noauth nolock local nodetach notty" + +Second pppd process without this patch prints into syslog following error: + + pppd 2.4.10-dev started by pali, uid 0 + Couldn't create new ppp unit: File exists + Exit. + +With this patch it falls back to random ppp unit id and succeeds: + + pppd 2.4.10-dev started by pali, uid 0 + Using interface ppp1361 + Connect: ppp1361 <--> /dev/pts/14 + ... + +Signed-off-by: Pali Rohár +--- + pppd/sys-linux.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/pppd/sys-linux.c ++++ b/pppd/sys-linux.c +@@ -873,6 +873,11 @@ static int make_ppp_unit(void) + ifunit = -1; + x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); + } ++ if (x < 0 && errno == EEXIST) { ++ srand(time(NULL) * getpid()); ++ ifunit = rand() % 10000; ++ x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); ++ } + if (x < 0) + error("Couldn't create new ppp unit: %m"); + diff --git a/package/network/services/ppp/patches/144-pppd-Retry-registering-interface-when-on-rtnetlink-E.patch b/package/network/services/ppp/patches/144-pppd-Retry-registering-interface-when-on-rtnetlink-E.patch new file mode 100644 index 00000000000..26c1e34683a --- /dev/null +++ b/package/network/services/ppp/patches/144-pppd-Retry-registering-interface-when-on-rtnetlink-E.patch @@ -0,0 +1,218 @@ +From 089687fbcc6524809ae9f4b2f8145fe3c2a91147 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Sat, 7 Aug 2021 19:48:01 +0200 +Subject: [PATCH] pppd: Retry registering interface when on rtnetlink -EBUSY + error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Due to workaround in kernel module ppp_generic.ko in function +ppp_nl_newlink(), kernel may return -EBUSY error to prevent possible +mutex deadlock. In this case userspace needs to retry its request. + +Proper way would be to fix kernel module to order requests and mutex +locking, so prevent deadlock in kernel and so never return this error to +userspace. Until it happens we need retry code in userspace. + +Signed-off-by: Pali Rohár +[ backport to ppp 2.4.9 ] +Signed-off-by: Christian Marangi +--- + pppd/sys-linux.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/pppd/sys-linux.c ++++ b/pppd/sys-linux.c +@@ -707,99 +707,101 @@ static int make_ppp_unit_rtnetlink(void) + int one; + int fd; + +- fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); +- if (fd < 0) { +- error("make_ppp_unit_rtnetlink: socket(NETLINK_ROUTE): %m (line %d)", __LINE__); +- return 0; +- } +- +- /* Tell kernel to not send to us payload of acknowledgment error message. */ +- one = 1; +- setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one)); ++ do { ++ fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); ++ if (fd < 0) { ++ error("make_ppp_unit_rtnetlink: socket(NETLINK_ROUTE): %m (line %d)", __LINE__); ++ return 0; ++ } ++ ++ /* Tell kernel to not send to us payload of acknowledgment error message. */ ++ one = 1; ++ setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one)); ++ ++ memset(&nladdr, 0, sizeof(nladdr)); ++ nladdr.nl_family = AF_NETLINK; ++ ++ if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) { ++ error("make_ppp_unit_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__); ++ close(fd); ++ return 0; ++ } ++ ++ memset(&nlreq, 0, sizeof(nlreq)); ++ nlreq.nlh.nlmsg_len = sizeof(nlreq); ++ nlreq.nlh.nlmsg_type = RTM_NEWLINK; ++ nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE; ++ nlreq.ifm.ifi_family = AF_UNSPEC; ++ nlreq.ifm.ifi_type = ARPHRD_NETROM; ++ nlreq.ifn.rta.rta_len = sizeof(nlreq.ifn); ++ nlreq.ifn.rta.rta_type = IFLA_IFNAME; ++ strlcpy(nlreq.ifn.ifname, req_ifname, sizeof(nlreq.ifn.ifname)); ++ nlreq.ifli.rta.rta_len = sizeof(nlreq.ifli); ++ nlreq.ifli.rta.rta_type = IFLA_LINKINFO; ++ nlreq.ifli.ifik.rta.rta_len = sizeof(nlreq.ifli.ifik); ++ nlreq.ifli.ifik.rta.rta_type = IFLA_INFO_KIND; ++ strcpy(nlreq.ifli.ifik.ifkind, "ppp"); ++ nlreq.ifli.ifid.rta.rta_len = sizeof(nlreq.ifli.ifid); ++ nlreq.ifli.ifid.rta.rta_type = IFLA_INFO_DATA; ++ nlreq.ifli.ifid.ifdata[0].rta.rta_len = sizeof(nlreq.ifli.ifid.ifdata[0]); ++ nlreq.ifli.ifid.ifdata[0].rta.rta_type = IFLA_PPP_DEV_FD; ++ nlreq.ifli.ifid.ifdata[0].ppp.ppp_dev_fd = ppp_dev_fd; ++ ++ memset(&nladdr, 0, sizeof(nladdr)); ++ nladdr.nl_family = AF_NETLINK; ++ ++ memset(&iov, 0, sizeof(iov)); ++ iov.iov_base = &nlreq; ++ iov.iov_len = sizeof(nlreq); ++ ++ memset(&msg, 0, sizeof(msg)); ++ msg.msg_name = &nladdr; ++ msg.msg_namelen = sizeof(nladdr); ++ msg.msg_iov = &iov; ++ msg.msg_iovlen = 1; ++ ++ if (sendmsg(fd, &msg, 0) < 0) { ++ error("make_ppp_unit_rtnetlink: sendmsg(RTM_NEWLINK/NLM_F_CREATE): %m (line %d)", __LINE__); ++ close(fd); ++ return 0; ++ } ++ ++ memset(&iov, 0, sizeof(iov)); ++ iov.iov_base = &nlresp; ++ iov.iov_len = sizeof(nlresp); ++ ++ memset(&msg, 0, sizeof(msg)); ++ msg.msg_name = &nladdr; ++ msg.msg_namelen = sizeof(nladdr); ++ msg.msg_iov = &iov; ++ msg.msg_iovlen = 1; ++ ++ nlresplen = recvmsg(fd, &msg, 0); ++ ++ if (nlresplen < 0) { ++ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): %m (line %d)", __LINE__); ++ close(fd); ++ return 0; ++ } + +- memset(&nladdr, 0, sizeof(nladdr)); +- nladdr.nl_family = AF_NETLINK; +- +- if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) { +- error("make_ppp_unit_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__); + close(fd); +- return 0; +- } +- +- memset(&nlreq, 0, sizeof(nlreq)); +- nlreq.nlh.nlmsg_len = sizeof(nlreq); +- nlreq.nlh.nlmsg_type = RTM_NEWLINK; +- nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE; +- nlreq.ifm.ifi_family = AF_UNSPEC; +- nlreq.ifm.ifi_type = ARPHRD_NETROM; +- nlreq.ifn.rta.rta_len = sizeof(nlreq.ifn); +- nlreq.ifn.rta.rta_type = IFLA_IFNAME; +- strlcpy(nlreq.ifn.ifname, req_ifname, sizeof(nlreq.ifn.ifname)); +- nlreq.ifli.rta.rta_len = sizeof(nlreq.ifli); +- nlreq.ifli.rta.rta_type = IFLA_LINKINFO; +- nlreq.ifli.ifik.rta.rta_len = sizeof(nlreq.ifli.ifik); +- nlreq.ifli.ifik.rta.rta_type = IFLA_INFO_KIND; +- strcpy(nlreq.ifli.ifik.ifkind, "ppp"); +- nlreq.ifli.ifid.rta.rta_len = sizeof(nlreq.ifli.ifid); +- nlreq.ifli.ifid.rta.rta_type = IFLA_INFO_DATA; +- nlreq.ifli.ifid.ifdata[0].rta.rta_len = sizeof(nlreq.ifli.ifid.ifdata[0]); +- nlreq.ifli.ifid.ifdata[0].rta.rta_type = IFLA_PPP_DEV_FD; +- nlreq.ifli.ifid.ifdata[0].ppp.ppp_dev_fd = ppp_dev_fd; +- +- memset(&nladdr, 0, sizeof(nladdr)); +- nladdr.nl_family = AF_NETLINK; +- +- memset(&iov, 0, sizeof(iov)); +- iov.iov_base = &nlreq; +- iov.iov_len = sizeof(nlreq); +- +- memset(&msg, 0, sizeof(msg)); +- msg.msg_name = &nladdr; +- msg.msg_namelen = sizeof(nladdr); +- msg.msg_iov = &iov; +- msg.msg_iovlen = 1; +- +- if (sendmsg(fd, &msg, 0) < 0) { +- error("make_ppp_unit_rtnetlink: sendmsg(RTM_NEWLINK/NLM_F_CREATE): %m (line %d)", __LINE__); +- close(fd); +- return 0; +- } +- +- memset(&iov, 0, sizeof(iov)); +- iov.iov_base = &nlresp; +- iov.iov_len = sizeof(nlresp); +- +- memset(&msg, 0, sizeof(msg)); +- msg.msg_name = &nladdr; +- msg.msg_namelen = sizeof(nladdr); +- msg.msg_iov = &iov; +- msg.msg_iovlen = 1; +- +- nlresplen = recvmsg(fd, &msg, 0); +- +- if (nlresplen < 0) { +- error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): %m (line %d)", __LINE__); +- close(fd); +- return 0; +- } +- +- close(fd); + +- if (nladdr.nl_family != AF_NETLINK) { +- error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not a netlink packet (line %d)", __LINE__); +- return 0; +- } +- +- if ((size_t)nlresplen < sizeof(nlresp) || nlresp.nlh.nlmsg_len < sizeof(nlresp)) { +- error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Acknowledgment netlink packet too short (line %d)", __LINE__); +- return 0; +- } +- +- /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */ +- if (nlresp.nlh.nlmsg_type != NLMSG_ERROR) { +- error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not an acknowledgment netlink packet (line %d)", __LINE__); +- return 0; +- } ++ if (nladdr.nl_family != AF_NETLINK) { ++ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not a netlink packet (line %d)", __LINE__); ++ return 0; ++ } ++ ++ if ((size_t)nlresplen < sizeof(nlresp) || nlresp.nlh.nlmsg_len < sizeof(nlresp)) { ++ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Acknowledgment netlink packet too short (line %d)", __LINE__); ++ return 0; ++ } ++ ++ /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */ ++ if (nlresp.nlh.nlmsg_type != NLMSG_ERROR) { ++ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not an acknowledgment netlink packet (line %d)", __LINE__); ++ return 0; ++ } ++ } while (nlresp.nlerr.error == -EBUSY); + + /* error == 0 indicates success, negative value is errno code */ + if (nlresp.nlerr.error != 0) { diff --git a/package/network/services/ppp/patches/208-fix_status_code.patch b/package/network/services/ppp/patches/208-fix_status_code.patch index 54e6c45e149..1d991e79490 100644 --- a/package/network/services/ppp/patches/208-fix_status_code.patch +++ b/package/network/services/ppp/patches/208-fix_status_code.patch @@ -12,7 +12,7 @@ Signed-off-by: Jo-Philipp Wich --- a/pppd/main.c +++ b/pppd/main.c -@@ -1034,7 +1034,8 @@ get_input(void) +@@ -1035,7 +1035,8 @@ get_input(void) } notice("Modem hangup"); hungup = 1; diff --git a/package/network/services/ppp/patches/321-multilink_support_custom_iface_names.patch b/package/network/services/ppp/patches/321-multilink_support_custom_iface_names.patch index 0c4d7ea9d6c..0ae84ae1ed9 100644 --- a/package/network/services/ppp/patches/321-multilink_support_custom_iface_names.patch +++ b/package/network/services/ppp/patches/321-multilink_support_custom_iface_names.patch @@ -119,7 +119,7 @@ Signed-off-by: George Kashperko && memcmp(vd.dptr, key.dptr, vd.dsize) == 0; --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c -@@ -706,6 +706,16 @@ void cfg_bundle(int mrru, int mtru, int +@@ -923,6 +923,16 @@ void cfg_bundle(int mrru, int mtru, int add_fd(ppp_dev_fd); } @@ -136,7 +136,7 @@ Signed-off-by: George Kashperko /* * make_new_bundle - create a new PPP unit (i.e. a bundle) * and connect our channel to it. This should only get called -@@ -724,6 +734,8 @@ void make_new_bundle(int mrru, int mtru, +@@ -941,6 +951,8 @@ void make_new_bundle(int mrru, int mtru, /* set the mrru and flags */ cfg_bundle(mrru, mtru, rssn, tssn); diff --git a/package/network/services/ppp/patches/330-retain_foreign_default_routes.patch b/package/network/services/ppp/patches/330-retain_foreign_default_routes.patch index 6ccc4507b2b..3d2a815dbd9 100644 --- a/package/network/services/ppp/patches/330-retain_foreign_default_routes.patch +++ b/package/network/services/ppp/patches/330-retain_foreign_default_routes.patch @@ -12,7 +12,7 @@ Signed-off-by: Jo-Philipp Wich --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c -@@ -1770,6 +1770,7 @@ int cifdefaultroute (int unit, u_int32_t +@@ -2248,6 +2248,7 @@ int cifdefaultroute (int unit, u_int32_t SIN_ADDR(rt.rt_genmask) = 0L; } diff --git a/package/network/services/ppp/patches/340-populate_default_gateway.patch b/package/network/services/ppp/patches/340-populate_default_gateway.patch index 0f965c705d2..64d03fb5c47 100644 --- a/package/network/services/ppp/patches/340-populate_default_gateway.patch +++ b/package/network/services/ppp/patches/340-populate_default_gateway.patch @@ -13,7 +13,7 @@ Signed-off-by: Jo-Philipp Wich --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c -@@ -1720,6 +1720,9 @@ int sifdefaultroute (int unit, u_int32_t +@@ -2198,6 +2198,9 @@ int sifdefaultroute (int unit, u_int32_t memset (&rt, 0, sizeof (rt)); SET_SA_FAMILY (rt.rt_dst, AF_INET); @@ -23,7 +23,7 @@ Signed-off-by: Jo-Philipp Wich rt.rt_dev = ifname; rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */ -@@ -1728,7 +1731,7 @@ int sifdefaultroute (int unit, u_int32_t +@@ -2206,7 +2209,7 @@ int sifdefaultroute (int unit, u_int32_t SIN_ADDR(rt.rt_genmask) = 0L; } diff --git a/package/network/services/ppp/patches/400-simplify_kernel_checks.patch b/package/network/services/ppp/patches/400-simplify_kernel_checks.patch index 3c720483627..9d0ea9a0b84 100644 --- a/package/network/services/ppp/patches/400-simplify_kernel_checks.patch +++ b/package/network/services/ppp/patches/400-simplify_kernel_checks.patch @@ -10,7 +10,7 @@ Signed-off-by: Jo-Philipp Wich --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c -@@ -206,7 +206,7 @@ static int driver_is_old = 0; +@@ -235,7 +235,7 @@ static int driver_is_old = 0; static int restore_term = 0; /* 1 => we've munged the terminal */ static struct termios inittermios; /* Initial TTY termios */ @@ -19,7 +19,7 @@ Signed-off-by: Jo-Philipp Wich static char loop_name[20]; static unsigned char inbuf[512]; /* buffer for chars read from loopback */ -@@ -225,8 +225,8 @@ static int looped; /* 1 if using loop +@@ -254,8 +254,8 @@ static int looped; /* 1 if using loop static int link_mtu; /* mtu for the link (not bundle) */ static struct utsname utsname; /* for the kernel version */ @@ -29,7 +29,7 @@ Signed-off-by: Jo-Philipp Wich #define MAX_IFS 100 -@@ -1455,11 +1455,12 @@ int ccp_fatal_error (int unit) +@@ -1933,11 +1933,12 @@ int ccp_fatal_error (int unit) * * path_to_procfs - find the path to the proc file system mount point */ @@ -44,7 +44,7 @@ Signed-off-by: Jo-Philipp Wich struct mntent *mntent; FILE *fp; -@@ -1481,6 +1482,7 @@ static char *path_to_procfs(const char * +@@ -1959,6 +1960,7 @@ static char *path_to_procfs(const char * fclose (fp); } } @@ -52,7 +52,7 @@ Signed-off-by: Jo-Philipp Wich strlcpy(proc_path + proc_path_len, tail, sizeof(proc_path) - proc_path_len); -@@ -2365,15 +2367,19 @@ int ppp_available(void) +@@ -2843,15 +2845,19 @@ int ppp_available(void) int my_version, my_modification, my_patch; int osmaj, osmin, ospatch; @@ -72,7 +72,7 @@ Signed-off-by: Jo-Philipp Wich /* XXX should get from driver */ driver_version = 2; -@@ -2433,6 +2439,7 @@ int ppp_available(void) +@@ -2911,6 +2917,7 @@ int ppp_available(void) if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP)) ok = 0; @@ -80,7 +80,7 @@ Signed-off-by: Jo-Philipp Wich /* * This is the PPP device. Validate the version of the driver at this -@@ -3106,6 +3113,7 @@ get_pty(int *master_fdp, int *slave_fdp, +@@ -3592,6 +3599,7 @@ get_pty(int *master_fdp, int *slave_fdp, } #endif /* TIOCGPTN */ @@ -88,7 +88,7 @@ Signed-off-by: Jo-Philipp Wich if (sfd < 0) { /* the old way - scan through the pty name space */ for (i = 0; i < 64; ++i) { -@@ -3124,6 +3132,7 @@ get_pty(int *master_fdp, int *slave_fdp, +@@ -3610,6 +3618,7 @@ get_pty(int *master_fdp, int *slave_fdp, } } } diff --git a/package/network/services/ppp/patches/401-no_record_file.patch b/package/network/services/ppp/patches/401-no_record_file.patch index 78442606851..0304f36fe2b 100644 --- a/package/network/services/ppp/patches/401-no_record_file.patch +++ b/package/network/services/ppp/patches/401-no_record_file.patch @@ -7,7 +7,7 @@ Signed-off-by: Jo-Philipp Wich --- a/pppd/pppd.h +++ b/pppd/pppd.h -@@ -317,7 +317,6 @@ extern int holdoff; /* Dead time before +@@ -318,7 +318,6 @@ extern int holdoff; /* Dead time before extern bool holdoff_specified; /* true if user gave a holdoff value */ extern bool notty; /* Stdin/out is not a tty */ extern char *pty_socket; /* Socket to connect to pty */ diff --git a/package/network/services/ppp/patches/403-no_wtmp.patch b/package/network/services/ppp/patches/403-no_wtmp.patch index 772620ed722..90c2a8208a5 100644 --- a/package/network/services/ppp/patches/403-no_wtmp.patch +++ b/package/network/services/ppp/patches/403-no_wtmp.patch @@ -7,7 +7,7 @@ Signed-off-by: Jo-Philipp Wich --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c -@@ -2503,6 +2503,7 @@ int ppp_available(void) +@@ -2981,6 +2981,7 @@ int ppp_available(void) void logwtmp (const char *line, const char *name, const char *host) { @@ -15,7 +15,7 @@ Signed-off-by: Jo-Philipp Wich struct utmp ut, *utp; pid_t mypid = getpid(); #if __GLIBC__ < 2 -@@ -2568,6 +2569,7 @@ void logwtmp (const char *line, const ch +@@ -3046,6 +3047,7 @@ void logwtmp (const char *line, const ch close (wtmp); } #endif diff --git a/package/network/services/ppp/patches/404-remove_obsolete_protocol_names.patch b/package/network/services/ppp/patches/404-remove_obsolete_protocol_names.patch index b9b6f0e593b..8bed425a5b3 100644 --- a/package/network/services/ppp/patches/404-remove_obsolete_protocol_names.patch +++ b/package/network/services/ppp/patches/404-remove_obsolete_protocol_names.patch @@ -7,7 +7,7 @@ Signed-off-by: Jo-Philipp Wich --- a/pppd/main.c +++ b/pppd/main.c -@@ -866,14 +866,17 @@ struct protocol_list { +@@ -867,14 +867,17 @@ struct protocol_list { const char *name; } protocol_list[] = { { 0x21, "IP" }, @@ -25,7 +25,7 @@ Signed-off-by: Jo-Philipp Wich { 0x33, "Stream Protocol ST-II" }, { 0x35, "Banyan Vines" }, { 0x39, "AppleTalk EDDP" }, -@@ -887,8 +890,11 @@ struct protocol_list { +@@ -888,8 +891,11 @@ struct protocol_list { { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" }, { 0x4b, "SNA over 802.2" }, { 0x4d, "SNA" }, @@ -37,7 +37,7 @@ Signed-off-by: Jo-Philipp Wich { 0x53, "Encryption" }, { 0x55, "Individual Link Encryption" }, { 0x57, "IPv6" }, -@@ -899,12 +905,15 @@ struct protocol_list { +@@ -900,12 +906,15 @@ struct protocol_list { { 0x65, "RTP IPHC Compressed non-TCP" }, { 0x67, "RTP IPHC Compressed UDP 8" }, { 0x69, "RTP IPHC Compressed RTP 8" }, @@ -53,7 +53,7 @@ Signed-off-by: Jo-Philipp Wich { 0x0203, "IBM Source Routing BPDU" }, { 0x0205, "DEC LANBridge100 Spanning Tree" }, { 0x0207, "Cisco Discovery Protocol" }, -@@ -916,15 +925,19 @@ struct protocol_list { +@@ -917,15 +926,19 @@ struct protocol_list { { 0x0231, "Luxcom" }, { 0x0233, "Sigma Network Systems" }, { 0x0235, "Apple Client Server Protocol" }, @@ -73,7 +73,7 @@ Signed-off-by: Jo-Philipp Wich { 0x4001, "Cray Communications Control Protocol" }, { 0x4003, "CDPD Mobile Network Registration Protocol" }, { 0x4005, "Expand accelerator protocol" }, -@@ -935,8 +948,10 @@ struct protocol_list { +@@ -936,8 +949,10 @@ struct protocol_list { { 0x4023, "RefTek Protocol" }, { 0x4025, "Fibre Channel" }, { 0x4027, "EMIT Protocols" }, @@ -84,7 +84,7 @@ Signed-off-by: Jo-Philipp Wich { 0x8023, "OSI Network Layer Control Protocol" }, { 0x8025, "Xerox NS IDP Control Protocol" }, { 0x8027, "DECnet Phase IV Control Protocol" }, -@@ -945,7 +960,9 @@ struct protocol_list { +@@ -946,7 +961,9 @@ struct protocol_list { { 0x8031, "Bridging NCP" }, { 0x8033, "Stream Protocol Control Protocol" }, { 0x8035, "Banyan Vines Control Protocol" }, @@ -94,7 +94,7 @@ Signed-off-by: Jo-Philipp Wich { 0x803f, "NETBIOS Framing Control Protocol" }, { 0x8041, "Cisco Systems Control Protocol" }, { 0x8043, "Ascom Timeplex" }, -@@ -954,18 +971,24 @@ struct protocol_list { +@@ -955,18 +972,24 @@ struct protocol_list { { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" }, { 0x804b, "SNA over 802.2 Control Protocol" }, { 0x804d, "SNA Control Protocol" }, @@ -119,7 +119,7 @@ Signed-off-by: Jo-Philipp Wich { 0x8207, "Cisco Discovery Protocol Control" }, { 0x8209, "Netcs Twin Routing" }, { 0x820b, "STP - Control Protocol" }, -@@ -974,24 +997,29 @@ struct protocol_list { +@@ -975,24 +998,29 @@ struct protocol_list { { 0x8281, "MPLSCP" }, { 0x8285, "IEEE p1284.4 standard - Protocol Control" }, { 0x8287, "ETSI TETRA TNP1 Control Protocol" }, diff --git a/package/network/utils/layerscape/restool/Makefile b/package/network/utils/layerscape/restool/Makefile index 5f938a854b0..5919f42ff2a 100644 --- a/package/network/utils/layerscape/restool/Makefile +++ b/package/network/utils/layerscape/restool/Makefile @@ -12,7 +12,7 @@ PKG_VERSION:=21.08 PKG_RELEASE:=4 PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://source.codeaurora.org/external/qoriq/qoriq-components/restool +PKG_SOURCE_URL:=https://github.com/nxp-qoriq/restool PKG_SOURCE_VERSION:=LSDK-21.08 PKG_MIRROR_HASH:=0396644927b8f3da20183227562f695c8063d3d4c6bb606e8f31dda450e962e4 diff --git a/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh b/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh index c271cb86607..6c5104bccd8 100755 --- a/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh +++ b/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh @@ -11,6 +11,7 @@ proto_qmi_init_config() { no_device=1 proto_config_add_string "device:device" proto_config_add_string apn + proto_config_add_string v6apn proto_config_add_string auth proto_config_add_string username proto_config_add_string password @@ -19,6 +20,7 @@ proto_qmi_init_config() { proto_config_add_string modes proto_config_add_string pdptype proto_config_add_int profile + proto_config_add_int v6profile proto_config_add_boolean dhcp proto_config_add_boolean dhcpv6 proto_config_add_boolean autoconnect @@ -31,14 +33,14 @@ proto_qmi_init_config() { proto_qmi_setup() { local interface="$1" local dataformat connstat plmn_mode mcc mnc - local device apn auth username password pincode delay modes pdptype - local profile dhcp dhcpv6 autoconnect plmn timeout mtu $PROTO_DEFAULT_OPTIONS + local device apn v6apn auth username password pincode delay modes pdptype + local profile v6profile dhcp dhcpv6 autoconnect plmn timeout mtu $PROTO_DEFAULT_OPTIONS local ip4table ip6table local cid_4 pdh_4 cid_6 pdh_6 local ip_6 ip_prefix_length gateway_6 dns1_6 dns2_6 - json_get_vars device apn auth username password pincode delay modes - json_get_vars pdptype profile dhcp dhcpv6 autoconnect plmn ip4table + json_get_vars device apn v6apn auth username password pincode delay modes + json_get_vars pdptype profile v6profile dhcp dhcpv6 autoconnect plmn ip4table json_get_vars ip6table timeout mtu $PROTO_DEFAULT_OPTIONS [ "$timeout" = "" ] && timeout="10" @@ -309,10 +311,13 @@ proto_qmi_setup() { uqmi -s -d "$device" --set-client-id wds,"$cid_6" --set-ip-family ipv6 > /dev/null 2>&1 + : "${v6apn:=${apn}}" + : "${v6profile:=${profile}}" + pdh_6=$(uqmi -s -d "$device" --set-client-id wds,"$cid_6" \ --start-network \ - ${apn:+--apn $apn} \ - ${profile:+--profile $profile} \ + ${v6apn:+--apn $v6apn} \ + ${v6profile:+--profile $v6profile} \ ${auth:+--auth-type $auth} \ ${username:+--username $username} \ ${password:+--password $password} \ @@ -383,6 +388,7 @@ proto_qmi_setup() { json_init json_add_string name "${interface}_6" json_add_string ifname "@$interface" + [ "$pdptype" = "ipv4v6" ] && json_add_string iface_464xlat "0" json_add_string proto "dhcpv6" [ -n "$ip6table" ] && json_add_string ip6table "$ip6table" proto_add_dynamic_defaults diff --git a/scripts/qemustart b/scripts/qemustart index 764b0e65afa..f6a46551294 100755 --- a/scripts/qemustart +++ b/scripts/qemustart @@ -109,10 +109,10 @@ Examples $SELF malta be -m 64 $SELF malta le64 $SELF malta be-glibc - $SELF armvirt 32 \\ + $SELF armsr armv7 \\ --machine virt,highmem=off \\ - --kernel bin/targets/armvirt/32/openwrt-armvirt-32-zImage \\ - --rootfs bin/targets/armvirt/32/openwrt-armvirt-32-root.ext4 + --kernel bin/targets/armsr/armv7/openwrt-armsr-armv7-generic-kernel.bin \\ + --rootfs bin/targets/armsr/armv7/openwrt-armsr-armv7-generic-ext4-rootfs.img EOF } @@ -162,7 +162,7 @@ parse_args() { o_bindir="${CONFIG_BINARY_FOLDER:-bin}/targets/$o_target/$o_subtarget" } -start_qemu_armvirt() { +start_qemu_armsr() { local kernel="$o_kernel" local rootfs="$o_rootfs" local mach="${o_mach:-virt}" @@ -170,15 +170,15 @@ start_qemu_armvirt() { local qemu_exe case "${o_subtarget%-*}" in - 32) + armv7) qemu_exe="qemu-system-arm" cpu="cortex-a15" - [ -n "$kernel" ] || kernel="$o_bindir/openwrt-$o_target-${o_subtarget%-*}-zImage-initramfs" + [ -n "$kernel" ] || kernel="$o_bindir/openwrt-$o_target-${o_subtarget%-*}-generic-initramfs-kernel.bin" ;; - 64) + armv8) qemu_exe="qemu-system-aarch64" cpu="cortex-a57" - [ -n "$kernel" ] || kernel="$o_bindir/openwrt-$o_target-${o_subtarget%-*}-Image-initramfs" + [ -n "$kernel" ] || kernel="$o_bindir/openwrt-$o_target-${o_subtarget%-*}-generic-initramfs-kernel.bin" ;; *) __errmsg "target $o_target: unknown subtarget $o_subtarget" @@ -328,7 +328,7 @@ start_qemu_x86() { start_qemu() { case "$o_target" in - armvirt) start_qemu_armvirt ;; + armsr) start_qemu_armsr ;; malta) start_qemu_malta ;; x86) start_qemu_x86 ;; *) diff --git a/scripts/sercomm-kernel-header.py b/scripts/sercomm-kernel-header.py index bfb29c6fe07..40bcbb13853 100755 --- a/scripts/sercomm-kernel-header.py +++ b/scripts/sercomm-kernel-header.py @@ -48,12 +48,12 @@ def get_kernel_header(args): struct.pack_into(' openwrt-arm-32.img +gunzip -c bin/targets/armsr/armv7/openwrt-armsr-armv7-generic-ext4-combined.img.gz > openwrt-arm-32.img qemu-system-arm -nographic \ -cpu cortex-a15 -machine virt \ - -bios QEMU_EFI_32.fd \ + -bios bin/targets/armsr/armv7/u-boot-qemu_armv7/u-boot.bin \ -smp 1 -m 1024 \ -device virtio-rng-pci \ -drive file=openwrt-arm-32.img,format=raw,index=0,media=disk \ @@ -56,17 +60,16 @@ qemu-system-arm -nographic \ -netdev user,id=testwan -net nic,netdev=testwan 64-bit: -gunzip -c bin/targets/armvirt/64/openwrt-armvirt-64-generic-ext4-combined.img.gz > openwrt-arm-64.img +gunzip -c bin/targets/armsr/armv8/openwrt-armsr-armv8-generic-ext4-combined.img.gz > openwrt-arm-64.img qemu-system-aarch64 -nographic \ -cpu cortex-a53 -machine virt \ - -bios QEMU_EFI_64.fd \ + -bios bin/targets/armsr/armv8/u-boot-qemu_armv8/u-boot.bin \ -smp 1 -m 1024 \ -device virtio-rng-pci \ -drive file=openwrt-arm-64.img,format=raw,index=0,media=disk \ -netdev user,id=testlan -net nic,netdev=testlan \ -netdev user,id=testwan -net nic,netdev=testwan -One can find EFI/BIOS binaries from: -- Compile mainline U-Boot for the QEMU ARM virtual machine (qemu_arm_defconfig/qemu_arm64_defconfig) -- From distribution packages (such as qemu-efi-arm and qemu-efi-aarch64 in Debian) +One can obtain other EFI/BIOS binaries from: +- Distribution packages (such as qemu-efi-arm and qemu-efi-aarch64 in Debian) - Community builds, like retrage/edk2-nightly: https://retrage.github.io/edk2-nightly/ diff --git a/target/linux/armvirt/32/config-6.1 b/target/linux/armsr/armv7/config-6.1 similarity index 100% rename from target/linux/armvirt/32/config-6.1 rename to target/linux/armsr/armv7/config-6.1 diff --git a/target/linux/armvirt/32/target.mk b/target/linux/armsr/armv7/target.mk similarity index 70% rename from target/linux/armvirt/32/target.mk rename to target/linux/armsr/armv7/target.mk index df220402411..fbad3abb260 100644 --- a/target/linux/armvirt/32/target.mk +++ b/target/linux/armsr/armv7/target.mk @@ -1,6 +1,6 @@ ARCH:=arm -SUBTARGET:=32 -BOARDNAME:=32-bit ARM QEMU Virtual Machine +SUBTARGET:=armv7 +BOARDNAME:=32-bit (armv7) machines CPU_TYPE:=cortex-a15 CPU_SUBTYPE:=neon-vfpv4 KERNELNAME:=zImage diff --git a/target/linux/armvirt/64/config-6.1 b/target/linux/armsr/armv8/config-6.1 similarity index 100% rename from target/linux/armvirt/64/config-6.1 rename to target/linux/armsr/armv8/config-6.1 diff --git a/target/linux/armvirt/64/target.mk b/target/linux/armsr/armv8/target.mk similarity index 69% rename from target/linux/armvirt/64/target.mk rename to target/linux/armsr/armv8/target.mk index ac5a60d848b..654e5976cae 100644 --- a/target/linux/armvirt/64/target.mk +++ b/target/linux/armsr/armv8/target.mk @@ -1,6 +1,6 @@ ARCH:=aarch64 -SUBTARGET:=64 -BOARDNAME:=64-bit ARM machines +SUBTARGET:=armv8 +BOARDNAME:=64-bit (armv8) machines define Target/Description Build multi-platform images for the ARMv8 instruction set architecture diff --git a/target/linux/armvirt/base-files/etc/board.d/01_led b/target/linux/armsr/base-files/etc/board.d/01_led similarity index 100% rename from target/linux/armvirt/base-files/etc/board.d/01_led rename to target/linux/armsr/base-files/etc/board.d/01_led diff --git a/target/linux/armvirt/base-files/etc/board.d/02_network b/target/linux/armsr/base-files/etc/board.d/02_network similarity index 100% rename from target/linux/armvirt/base-files/etc/board.d/02_network rename to target/linux/armsr/base-files/etc/board.d/02_network diff --git a/target/linux/armvirt/base-files/etc/board.d/03_gpio_switches b/target/linux/armsr/base-files/etc/board.d/03_gpio_switches similarity index 100% rename from target/linux/armvirt/base-files/etc/board.d/03_gpio_switches rename to target/linux/armsr/base-files/etc/board.d/03_gpio_switches diff --git a/target/linux/armvirt/base-files/etc/inittab b/target/linux/armsr/base-files/etc/inittab similarity index 100% rename from target/linux/armvirt/base-files/etc/inittab rename to target/linux/armsr/base-files/etc/inittab diff --git a/target/linux/armvirt/base-files/lib/preinit/01_sysinfo_acpi b/target/linux/armsr/base-files/lib/preinit/01_sysinfo_acpi similarity index 100% rename from target/linux/armvirt/base-files/lib/preinit/01_sysinfo_acpi rename to target/linux/armsr/base-files/lib/preinit/01_sysinfo_acpi diff --git a/target/linux/armvirt/base-files/lib/upgrade/platform.sh b/target/linux/armsr/base-files/lib/upgrade/platform.sh similarity index 100% rename from target/linux/armvirt/base-files/lib/upgrade/platform.sh rename to target/linux/armsr/base-files/lib/upgrade/platform.sh diff --git a/target/linux/armvirt/config-6.1 b/target/linux/armsr/config-6.1 similarity index 100% rename from target/linux/armvirt/config-6.1 rename to target/linux/armsr/config-6.1 diff --git a/target/linux/armvirt/image/Makefile b/target/linux/armsr/image/Makefile similarity index 97% rename from target/linux/armvirt/image/Makefile rename to target/linux/armsr/image/Makefile index 8642c88a499..a6f045d24f5 100644 --- a/target/linux/armvirt/image/Makefile +++ b/target/linux/armsr/image/Makefile @@ -73,7 +73,7 @@ define Build/grub-install $(INSTALL_DIR) $@.grub2 endef -DEVICE_VARS += GRUB2_VARIANT +DEVICE_VARS += GRUB2_VARIANT UBOOT define Device/efi-default IMAGE/rootfs.img := append-rootfs | pad-to $(ROOTFS_PARTSIZE) IMAGE/rootfs.img.gz := append-rootfs | pad-to $(ROOTFS_PARTSIZE) | gzip @@ -105,6 +105,7 @@ define Device/generic DEVICE_TITLE := Generic EFI Boot GRUB2_VARIANT := generic FILESYSTEMS := ext4 squashfs + UBOOT := $(if $(CONFIG_aarch64),qemu_armv8,qemu_armv7) DEVICE_PACKAGES += kmod-amazon-ena kmod-e1000e kmod-vmxnet3 kmod-rtc-rx8025 \ kmod-i2c-mux-pca954x kmod-gpio-pca953x partx-utils kmod-wdt-sp805 \ kmod-mvneta kmod-mvpp2 kmod-fsl-dpaa1-net kmod-fsl-dpaa2-net \ diff --git a/target/linux/armvirt/image/grub-efi.cfg b/target/linux/armsr/image/grub-efi.cfg similarity index 100% rename from target/linux/armvirt/image/grub-efi.cfg rename to target/linux/armsr/image/grub-efi.cfg diff --git a/target/linux/armvirt/modules.mk b/target/linux/armsr/modules.mk similarity index 89% rename from target/linux/armvirt/modules.mk rename to target/linux/armsr/modules.mk index c59301aae7e..7a349337d8a 100644 --- a/target/linux/armvirt/modules.mk +++ b/target/linux/armsr/modules.mk @@ -1,7 +1,7 @@ define KernelPackage/acpi-mdio SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=ACPI MDIO support - DEPENDS:=@(TARGET_armvirt_64) +kmod-libphy +kmod-mdio-devres + DEPENDS:=@(TARGET_armsr_armv8) +kmod-libphy +kmod-mdio-devres KCONFIG:=CONFIG_ACPI_MDIO FILES:=$(LINUX_DIR)/drivers/net/mdio/acpi_mdio.ko AUTOLOAD:=$(call AutoLoad,11,acpi_mdio) @@ -15,7 +15,7 @@ $(eval $(call KernelPackage,acpi-mdio)) define KernelPackage/fsl-pcs-lynx SUBMENU=$(NETWORK_DEVICES_MENU) - DEPENDS:=@(TARGET_armvirt_64) +kmod-libphy +kmod-of-mdio +kmod-phylink + DEPENDS:=@(TARGET_armsr_armv8) +kmod-libphy +kmod-of-mdio +kmod-phylink TITLE:=NXP (Freescale) Lynx PCS HIDDEN:=1 KCONFIG:=CONFIG_PCS_LYNX @@ -28,7 +28,7 @@ $(eval $(call KernelPackage,fsl-pcs-lynx)) define KernelPackage/pcs-xpcs SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=Synopsis DesignWare PCS driver - DEPENDS:=@(TARGET_armvirt_64) +kmod-phylink + DEPENDS:=@(TARGET_armsr_armv8) +kmod-phylink KCONFIG:=CONFIG_PCS_XPCS FILES:=$(LINUX_DIR)/drivers/net/pcs/pcs_xpcs.ko AUTOLOAD:=$(call AutoLoad,20,pcs_xpcs) @@ -38,7 +38,7 @@ $(eval $(call KernelPackage,pcs-xpcs)) define KernelPackage/fsl-fec SUBMENU:=$(NETWORK_DEVICES_MENU) - DEPENDS:=@(TARGET_armvirt_64) +kmod-libphy +kmod-of-mdio \ + DEPENDS:=@(TARGET_armsr_armv8) +kmod-libphy +kmod-of-mdio \ +kmod-ptp +kmod-net-selftests TITLE:=NXP (Freescale) FEC Ethernet controller (i.MX) KCONFIG:=CONFIG_FEC @@ -50,7 +50,7 @@ $(eval $(call KernelPackage,fsl-fec)) define KernelPackage/fsl-xgmac-mdio SUBMENU=$(NETWORK_DEVICES_MENU) - DEPENDS:=@(TARGET_armvirt_64) +kmod-libphy +kmod-of-mdio +kmod-acpi-mdio + DEPENDS:=@(TARGET_armsr_armv8) +kmod-libphy +kmod-of-mdio +kmod-acpi-mdio TITLE:=NXP (Freescale) MDIO bus KCONFIG:=CONFIG_FSL_XGMAC_MDIO FILES=$(LINUX_DIR)/drivers/net/ethernet/freescale/xgmac_mdio.ko @@ -74,7 +74,7 @@ $(eval $(call KernelPackage,fsl-mc-dpio)) define KernelPackage/fsl-enetc-net SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=:NXP ENETC (LS1028A) Ethernet - DEPENDS:=@(TARGET_armvirt_64) +kmod-phylink +kmod-fsl-pcs-lynx + DEPENDS:=@(TARGET_armsr_armv8) +kmod-phylink +kmod-fsl-pcs-lynx KCONFIG:= \ CONFIG_FSL_ENETC \ CONFIG_FSL_ENETC_VF \ @@ -92,7 +92,7 @@ $(eval $(call KernelPackage,fsl-enetc-net)) define KernelPackage/fsl-dpaa1-net SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=NXP DPAA1 (LS1043/LS1046) Ethernet - DEPENDS:=@(TARGET_armvirt_64) +kmod-fsl-xgmac-mdio +kmod-libphy +kmod-crypto-crc32 + DEPENDS:=@(TARGET_armsr_armv8) +kmod-fsl-xgmac-mdio +kmod-libphy +kmod-crypto-crc32 KCONFIG:= \ CONFIG_FSL_DPAA=y \ CONFIG_FSL_DPAA_ETH \ @@ -112,7 +112,7 @@ $(eval $(call KernelPackage,fsl-dpaa1-net)) define KernelPackage/fsl-dpaa2-net SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=NXP DPAA2 Ethernet - DEPENDS:=@(TARGET_armvirt_64) +kmod-fsl-xgmac-mdio +kmod-phylink \ + DEPENDS:=@(TARGET_armsr_armv8) +kmod-fsl-xgmac-mdio +kmod-phylink \ +kmod-fsl-pcs-lynx +kmod-fsl-mc-dpio KCONFIG:= \ CONFIG_FSL_MC_UAPI_SUPPORT=y \ @@ -127,7 +127,7 @@ $(eval $(call KernelPackage,fsl-dpaa2-net)) define KernelPackage/fsl-dpaa2-console SUBMENU:=$(OTHER_MENU) TITLE:=NXP DPAA2 Debug console - DEPENDS:=@(TARGET_armvirt_64) + DEPENDS:=@(TARGET_armsr_armv8) KCONFIG:=CONFIG_DPAA2_CONSOLE FILES=$(LINUX_DIR)/drivers/soc/fsl/dpaa2-console.ko AUTOLOAD=$(call AutoLoad,40,dpaa2-console) @@ -143,7 +143,7 @@ $(eval $(call KernelPackage,fsl-dpaa2-console)) define KernelPackage/marvell-mdio SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=Marvell Armada platform MDIO driver - DEPENDS:=@(TARGET_armvirt_64) +kmod-libphy +kmod-of-mdio +kmod-acpi-mdio + DEPENDS:=@(TARGET_armsr_armv8) +kmod-libphy +kmod-of-mdio +kmod-acpi-mdio KCONFIG:=CONFIG_MVMDIO FILES=$(LINUX_DIR)/drivers/net/ethernet/marvell/mvmdio.ko AUTOLOAD=$(call AutoLoad,30,marvell-mdio) @@ -154,7 +154,7 @@ $(eval $(call KernelPackage,marvell-mdio)) define KernelPackage/phy-marvell-10g SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=Marvell Alaska 10G PHY driver - DEPENDS:=@(TARGET_armvirt_64) +kmod-libphy + DEPENDS:=@(TARGET_armsr_armv8) +kmod-libphy KCONFIG:=CONFIG_MARVELL_10G_PHY FILES=$(LINUX_DIR)/drivers/net/phy/marvell10g.ko AUTOLOAD=$(call AutoLoad,35,marvell10g) @@ -165,7 +165,7 @@ $(eval $(call KernelPackage,phy-marvell-10g)) define KernelPackage/mvneta SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=Marvell Armada 370/38x/XP/37xx network driver - DEPENDS:=@(TARGET_armvirt_64) +kmod-marvell-mdio +kmod-phylink + DEPENDS:=@(TARGET_armsr_armv8) +kmod-marvell-mdio +kmod-phylink KCONFIG:=CONFIG_MVNETA FILES:=$(LINUX_DIR)/drivers/net/ethernet/marvell/mvneta.ko AUTOLOAD=$(call AutoLoad,30,mvneta) @@ -176,7 +176,7 @@ $(eval $(call KernelPackage,mvneta)) define KernelPackage/mvpp2 SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=Marvell Armada 375/7K/8K network driver - DEPENDS:=@(TARGET_armvirt_64) +kmod-marvell-mdio +kmod-phylink + DEPENDS:=@(TARGET_armsr_armv8) +kmod-marvell-mdio +kmod-phylink KCONFIG:=CONFIG_MVPP2 \ CONFIG_MVPP2_PTP=n FILES=$(LINUX_DIR)/drivers/net/ethernet/marvell/mvpp2/mvpp2.ko @@ -208,7 +208,7 @@ $(eval $(call KernelPackage,imx7-ulp-wdt)) define KernelPackage/stmmac-core SUBMENU=$(NETWORK_DEVICES_MENU) TITLE:=Synopsis Ethernet Controller core (NXP,STMMicro,others) - DEPENDS:=@(TARGET_armvirt_64) +kmod-pcs-xpcs +kmod-ptp \ + DEPENDS:=@(TARGET_armsr_armv8) +kmod-pcs-xpcs +kmod-ptp \ +kmod-of-mdio KCONFIG:=CONFIG_STMMAC_ETH \ CONFIG_STMMAC_SELFTESTS=n \ @@ -259,7 +259,7 @@ $(eval $(call KernelPackage,dwmac-rockchip)) define KernelPackage/thunderx-net SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=Marvell (Cavium) ThunderX/2 network drivers - DEPENDS:=@(TARGET_armvirt_64) +kmod-phylink +kmod-of-mdio + DEPENDS:=@(TARGET_armsr_armv8) +kmod-phylink +kmod-of-mdio KCONFIG:=CONFIG_NET_VENDOR_CAVIUM \ CONFIG_THUNDER_NIC_PF \ CONFIG_THUNDER_NIC_VF \ diff --git a/target/linux/armvirt/patches-6.1/221-armvirt-disable-gc_sections.patch b/target/linux/armsr/patches-6.1/221-armsr-disable_gc_sections_armv7.patch similarity index 100% rename from target/linux/armvirt/patches-6.1/221-armvirt-disable-gc_sections.patch rename to target/linux/armsr/patches-6.1/221-armsr-disable_gc_sections_armv7.patch diff --git a/target/linux/armvirt/patches-6.1/701-v6.2-0001-net-dpaa2-eth-don-t-use-ENOTSUPP-error-code.patch b/target/linux/armsr/patches-6.1/701-v6.2-0001-net-dpaa2-eth-don-t-use-ENOTSUPP-error-code.patch similarity index 100% rename from target/linux/armvirt/patches-6.1/701-v6.2-0001-net-dpaa2-eth-don-t-use-ENOTSUPP-error-code.patch rename to target/linux/armsr/patches-6.1/701-v6.2-0001-net-dpaa2-eth-don-t-use-ENOTSUPP-error-code.patch diff --git a/target/linux/armvirt/patches-6.1/701-v6.2-0002-net-dpaa2-replace-dpaa2_mac_is_type_fixed-with-dpaa2.patch b/target/linux/armsr/patches-6.1/701-v6.2-0002-net-dpaa2-replace-dpaa2_mac_is_type_fixed-with-dpaa2.patch similarity index 100% rename from target/linux/armvirt/patches-6.1/701-v6.2-0002-net-dpaa2-replace-dpaa2_mac_is_type_fixed-with-dpaa2.patch rename to target/linux/armsr/patches-6.1/701-v6.2-0002-net-dpaa2-replace-dpaa2_mac_is_type_fixed-with-dpaa2.patch diff --git a/target/linux/armvirt/patches-6.1/701-v6.2-0003-net-dpaa2-mac-absorb-phylink_start-call-into-dpaa2_m.patch b/target/linux/armsr/patches-6.1/701-v6.2-0003-net-dpaa2-mac-absorb-phylink_start-call-into-dpaa2_m.patch similarity index 100% rename from target/linux/armvirt/patches-6.1/701-v6.2-0003-net-dpaa2-mac-absorb-phylink_start-call-into-dpaa2_m.patch rename to target/linux/armsr/patches-6.1/701-v6.2-0003-net-dpaa2-mac-absorb-phylink_start-call-into-dpaa2_m.patch diff --git a/target/linux/armvirt/patches-6.1/701-v6.2-0004-net-dpaa2-mac-remove-defensive-check-in-dpaa2_mac_di.patch b/target/linux/armsr/patches-6.1/701-v6.2-0004-net-dpaa2-mac-remove-defensive-check-in-dpaa2_mac_di.patch similarity index 100% rename from target/linux/armvirt/patches-6.1/701-v6.2-0004-net-dpaa2-mac-remove-defensive-check-in-dpaa2_mac_di.patch rename to target/linux/armsr/patches-6.1/701-v6.2-0004-net-dpaa2-mac-remove-defensive-check-in-dpaa2_mac_di.patch diff --git a/target/linux/armvirt/patches-6.1/701-v6.2-0005-net-dpaa2-eth-assign-priv-mac-after-dpaa2_mac_connec.patch b/target/linux/armsr/patches-6.1/701-v6.2-0005-net-dpaa2-eth-assign-priv-mac-after-dpaa2_mac_connec.patch similarity index 100% rename from target/linux/armvirt/patches-6.1/701-v6.2-0005-net-dpaa2-eth-assign-priv-mac-after-dpaa2_mac_connec.patch rename to target/linux/armsr/patches-6.1/701-v6.2-0005-net-dpaa2-eth-assign-priv-mac-after-dpaa2_mac_connec.patch diff --git a/target/linux/armvirt/patches-6.1/701-v6.2-0006-net-dpaa2-switch-assign-port_priv-mac-after-dpaa2_ma.patch b/target/linux/armsr/patches-6.1/701-v6.2-0006-net-dpaa2-switch-assign-port_priv-mac-after-dpaa2_ma.patch similarity index 100% rename from target/linux/armvirt/patches-6.1/701-v6.2-0006-net-dpaa2-switch-assign-port_priv-mac-after-dpaa2_ma.patch rename to target/linux/armsr/patches-6.1/701-v6.2-0006-net-dpaa2-switch-assign-port_priv-mac-after-dpaa2_ma.patch diff --git a/target/linux/armvirt/patches-6.1/701-v6.2-0007-net-dpaa2-publish-MAC-stringset-to-ethtool-S-even-if.patch b/target/linux/armsr/patches-6.1/701-v6.2-0007-net-dpaa2-publish-MAC-stringset-to-ethtool-S-even-if.patch similarity index 100% rename from target/linux/armvirt/patches-6.1/701-v6.2-0007-net-dpaa2-publish-MAC-stringset-to-ethtool-S-even-if.patch rename to target/linux/armsr/patches-6.1/701-v6.2-0007-net-dpaa2-publish-MAC-stringset-to-ethtool-S-even-if.patch diff --git a/target/linux/armvirt/patches-6.1/701-v6.2-0008-net-dpaa2-switch-replace-direct-MAC-access-with-dpaa.patch b/target/linux/armsr/patches-6.1/701-v6.2-0008-net-dpaa2-switch-replace-direct-MAC-access-with-dpaa.patch similarity index 100% rename from target/linux/armvirt/patches-6.1/701-v6.2-0008-net-dpaa2-switch-replace-direct-MAC-access-with-dpaa.patch rename to target/linux/armsr/patches-6.1/701-v6.2-0008-net-dpaa2-switch-replace-direct-MAC-access-with-dpaa.patch diff --git a/target/linux/armvirt/patches-6.1/701-v6.2-0009-net-dpaa2-eth-connect-to-MAC-before-requesting-the-e.patch b/target/linux/armsr/patches-6.1/701-v6.2-0009-net-dpaa2-eth-connect-to-MAC-before-requesting-the-e.patch similarity index 100% rename from target/linux/armvirt/patches-6.1/701-v6.2-0009-net-dpaa2-eth-connect-to-MAC-before-requesting-the-e.patch rename to target/linux/armsr/patches-6.1/701-v6.2-0009-net-dpaa2-eth-connect-to-MAC-before-requesting-the-e.patch diff --git a/target/linux/armvirt/patches-6.1/701-v6.2-0010-net-dpaa2-eth-serialize-changes-to-priv-mac-with-a-m.patch b/target/linux/armsr/patches-6.1/701-v6.2-0010-net-dpaa2-eth-serialize-changes-to-priv-mac-with-a-m.patch similarity index 100% rename from target/linux/armvirt/patches-6.1/701-v6.2-0010-net-dpaa2-eth-serialize-changes-to-priv-mac-with-a-m.patch rename to target/linux/armsr/patches-6.1/701-v6.2-0010-net-dpaa2-eth-serialize-changes-to-priv-mac-with-a-m.patch diff --git a/target/linux/armvirt/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch b/target/linux/armsr/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch similarity index 100% rename from target/linux/armvirt/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch rename to target/linux/armsr/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch diff --git a/target/linux/armvirt/patches-6.1/701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch b/target/linux/armsr/patches-6.1/701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch similarity index 100% rename from target/linux/armvirt/patches-6.1/701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch rename to target/linux/armsr/patches-6.1/701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch diff --git a/target/linux/armvirt/32/config-5.15 b/target/linux/armvirt/32/config-5.15 deleted file mode 100644 index 91a0c61ddd4..00000000000 --- a/target/linux/armvirt/32/config-5.15 +++ /dev/null @@ -1,77 +0,0 @@ -CONFIG_ALIGNMENT_TRAP=y -CONFIG_ARCH_32BIT_OFF_T=y -CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -CONFIG_ARCH_MULTIPLATFORM=y -CONFIG_ARCH_MULTI_V6_V7=y -CONFIG_ARCH_MULTI_V7=y -CONFIG_ARCH_NR_GPIO=0 -CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y -CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_ARCH_VIRT=y -CONFIG_ARM=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARM_CRYPTO=y -CONFIG_ARM_HAS_SG_CHAIN=y -CONFIG_ARM_HEAVY_MB=y -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_L1_CACHE_SHIFT_6=y -CONFIG_ARM_LPAE=y -CONFIG_ARM_PATCH_IDIV=y -CONFIG_ARM_PATCH_PHYS_VIRT=y -CONFIG_ARM_PSCI=y -CONFIG_ARM_THUMB=y -CONFIG_ARM_UNWIND=y -CONFIG_ARM_VIRT_EXT=y -CONFIG_AUTO_ZRELADDR=y -CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y -CONFIG_CACHE_L2X0=y -CONFIG_COMPAT_32BIT_TIME=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y -CONFIG_CPU_HAS_ASID=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_SPECTRE=y -CONFIG_CPU_THUMB_CAPABLE=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_V7=y -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -CONFIG_DMA_OPS=y -CONFIG_EDAC_ATOMIC_SCRUB=y -CONFIG_GENERIC_IRQ_MULTI_HANDLER=y -CONFIG_GENERIC_VDSO_32=y -CONFIG_HARDEN_BRANCH_PREDICTOR=y -CONFIG_HAVE_SMP=y -CONFIG_HZ_FIXED=0 -CONFIG_HZ_PERIODIC=y -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -CONFIG_MODULES_USE_ELF_REL=y -CONFIG_NEON=y -CONFIG_NR_CPUS=4 -CONFIG_OLD_SIGACTION=y -CONFIG_OLD_SIGSUSPEND3=y -CONFIG_OUTER_CACHE=y -CONFIG_OUTER_CACHE_SYNC=y -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_PERF_USE_VMALLOC=y -CONFIG_RTC_MC146818_LIB=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SMP_ON_UP=y -CONFIG_SWP_EMULATE=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -CONFIG_UNWINDER_ARM=y -CONFIG_USE_OF=y -CONFIG_VFP=y -CONFIG_VFPv3=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_ZBOOT_ROM_TEXT=0 diff --git a/target/linux/armvirt/64/config-5.15 b/target/linux/armvirt/64/config-5.15 deleted file mode 100644 index eb5405eb1ef..00000000000 --- a/target/linux/armvirt/64/config-5.15 +++ /dev/null @@ -1,154 +0,0 @@ -CONFIG_64BIT=y -CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y -CONFIG_ARCH_MMAP_RND_BITS=18 -CONFIG_ARCH_MMAP_RND_BITS_MAX=24 -CONFIG_ARCH_MMAP_RND_BITS_MIN=18 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 -CONFIG_ARCH_PROC_KCORE_TEXT=y -CONFIG_ARCH_STACKWALK=y -CONFIG_ARCH_VEXPRESS=y -CONFIG_ARCH_WANTS_NO_INSTR=y -CONFIG_ARM64=y -CONFIG_ARM64_4K_PAGES=y -CONFIG_ARM64_CNP=y -CONFIG_ARM64_CRYPTO=y -CONFIG_ARM64_EPAN=y -CONFIG_ARM64_ERRATUM_1165522=y -CONFIG_ARM64_ERRATUM_1286807=y -CONFIG_ARM64_ERRATUM_819472=y -CONFIG_ARM64_ERRATUM_824069=y -CONFIG_ARM64_ERRATUM_826319=y -CONFIG_ARM64_ERRATUM_827319=y -CONFIG_ARM64_ERRATUM_832075=y -CONFIG_ARM64_ERRATUM_843419=y -CONFIG_ARM64_HW_AFDBM=y -CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y -CONFIG_ARM64_PAGE_SHIFT=12 -CONFIG_ARM64_PAN=y -CONFIG_ARM64_PA_BITS=48 -CONFIG_ARM64_PA_BITS_48=y -CONFIG_ARM64_PTR_AUTH=y -CONFIG_ARM64_PTR_AUTH_KERNEL=y -CONFIG_ARM64_SVE=y -CONFIG_ARM64_TAGGED_ADDR_ABI=y -CONFIG_ARM64_VA_BITS=39 -CONFIG_ARM64_VA_BITS_39=y -CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y -CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y -CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y -CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y -CONFIG_ARM_SBSA_WATCHDOG=y -CONFIG_ATOMIC64_SELFTEST=y -CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y -CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_BLK_PM=y -CONFIG_CAVIUM_TX2_ERRATUM_219=y -CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y -CONFIG_CLK_SP810=y -CONFIG_CLK_VEXPRESS_OSC=y -# CONFIG_COMPAT_32BIT_TIME is not set -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_CPU_PM=y -CONFIG_CRYPTO_AES_ARM64=y -CONFIG_CRYPTO_AES_ARM64_BS=y -CONFIG_CRYPTO_AES_ARM64_CE=y -CONFIG_CRYPTO_AES_ARM64_CE_BLK=y -CONFIG_CRYPTO_AES_ARM64_CE_CCM=y -CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y -CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y -CONFIG_CRYPTO_BLAKE2S=y -CONFIG_CRYPTO_CHACHA20=y -CONFIG_CRYPTO_CHACHA20_NEON=y -CONFIG_CRYPTO_CRYPTD=y -CONFIG_CRYPTO_GHASH_ARM64_CE=y -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_CRYPTO_LIB_CHACHA_GENERIC=y -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA1_ARM64_CE=y -CONFIG_CRYPTO_SHA256_ARM64=y -CONFIG_CRYPTO_SHA2_ARM64_CE=y -CONFIG_CRYPTO_SHA512_ARM64=y -CONFIG_CRYPTO_SIMD=y -CONFIG_DMA_DIRECT_REMAP=y -CONFIG_DMA_SHARED_BUFFER=y -CONFIG_DRM=y -CONFIG_DRM_BOCHS=y -CONFIG_DRM_BRIDGE=y -CONFIG_DRM_GEM_SHMEM_HELPER=y -CONFIG_DRM_KMS_HELPER=y -CONFIG_DRM_PANEL=y -CONFIG_DRM_PANEL_BRIDGE=y -CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y -CONFIG_DRM_QXL=y -CONFIG_DRM_TTM=y -CONFIG_DRM_TTM_HELPER=y -CONFIG_DRM_VIRTIO_GPU=y -CONFIG_DRM_VRAM_HELPER=y -CONFIG_FB=y -CONFIG_FB_ARMCLCD=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_CMDLINE=y -CONFIG_FB_MODE_HELPERS=y -CONFIG_FRAME_POINTER=y -CONFIG_FSL_ERRATUM_A008585=y -CONFIG_FUJITSU_ERRATUM_010001=y -CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y -CONFIG_GENERIC_CSUM=y -CONFIG_GENERIC_FIND_FIRST_BIT=y -CONFIG_GPIO_GENERIC=y -CONFIG_GPIO_GENERIC_PLATFORM=y -CONFIG_HDMI=y -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_ARM_SMCCC_TRNG=y -CONFIG_HW_RANDOM_VIRTIO=y -CONFIG_I2C=y -CONFIG_I2C_ALGOBIT=y -CONFIG_I2C_BOARDINFO=y -CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 -CONFIG_KCMP=y -CONFIG_LCD_CLASS_DEVICE=m -# CONFIG_LCD_PLATFORM is not set -CONFIG_MFD_CORE=y -CONFIG_MFD_SYSCON=y -CONFIG_MFD_VEXPRESS_SYSREG=y -CONFIG_MMC=y -CONFIG_MMC_ARMMMCI=y -CONFIG_MODULES_USE_ELF_RELA=y -CONFIG_NEED_SG_DMA_LENGTH=y -CONFIG_NO_HZ=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NR_CPUS=64 -CONFIG_NVIDIA_CARMEL_CNP_ERRATUM=y -CONFIG_PM=y -CONFIG_PM_CLK=y -CONFIG_PM_GENERIC_DOMAINS=y -CONFIG_PM_GENERIC_DOMAINS_OF=y -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_VEXPRESS=y -CONFIG_POWER_SUPPLY=y -CONFIG_QUEUED_RWLOCKS=y -CONFIG_QUEUED_SPINLOCKS=y -CONFIG_REGMAP=y -CONFIG_REGMAP_MMIO=y -CONFIG_RODATA_FULL_DEFAULT_ENABLED=y -CONFIG_RTC_I2C_AND_SPI=y -CONFIG_SMC91X=y -CONFIG_SPARSEMEM=y -CONFIG_SPARSEMEM_EXTREME=y -CONFIG_SPARSEMEM_VMEMMAP=y -CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y -CONFIG_SYNC_FILE=y -CONFIG_SYSCTL_EXCEPTION_TRACE=y -CONFIG_THREAD_INFO_IN_TASK=y -CONFIG_UNMAP_KERNEL_AT_EL0=y -CONFIG_VEXPRESS_CONFIG=y -CONFIG_VIDEOMODE_HELPERS=y -CONFIG_VIRTIO_DMA_SHARED_BUFFER=y -CONFIG_VMAP_STACK=y -CONFIG_WATCHDOG_CORE=y -CONFIG_ZONE_DMA32=y diff --git a/target/linux/armvirt/config-5.15 b/target/linux/armvirt/config-5.15 deleted file mode 100644 index 36f7d9f01e3..00000000000 --- a/target/linux/armvirt/config-5.15 +++ /dev/null @@ -1,155 +0,0 @@ -CONFIG_9P_FS=y -# CONFIG_9P_FS_POSIX_ACL is not set -# CONFIG_9P_FS_SECURITY is not set -CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARM_AMBA=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -CONFIG_ARM_GIC=y -CONFIG_ARM_GIC_V2M=y -CONFIG_ARM_GIC_V3=y -CONFIG_ARM_GIC_V3_ITS=y -CONFIG_ARM_GIC_V3_ITS_PCI=y -CONFIG_ARM_PSCI_FW=y -CONFIG_BALLOON_COMPACTION=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BLK_MQ_VIRTIO=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_COMMON_CLK=y -CONFIG_CPU_RMAP=y -CONFIG_CRC16=y -CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_RNG2=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DMADEVICES=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_OF=y -CONFIG_DMA_REMAP=y -CONFIG_DTC=y -CONFIG_EDAC_SUPPORT=y -CONFIG_EXT4_FS=y -CONFIG_F2FS_FS=y -CONFIG_FAILOVER=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_FW_LOADER_PAGED_BUF=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ARCH_TOPOLOGY=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_CPU_VULNERABILITIES=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_GETTIMEOFDAY=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_MIGRATION=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_CDEV=y -CONFIG_GPIO_PL061=y -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HOTPLUG_CPU=y -CONFIG_HVC_DRIVER=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -CONFIG_JBD2=y -CONFIG_LIBFDT=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_MEMFD_CREATE=y -CONFIG_MEMORY_BALLOON=y -CONFIG_MIGRATION=y -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NET_9P=y -# CONFIG_NET_9P_DEBUG is not set -CONFIG_NET_9P_VIRTIO=y -CONFIG_NET_FAILOVER=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NLS=y -CONFIG_NVMEM=y -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IRQ=y -CONFIG_OF_KOBJ=y -CONFIG_PADATA=y -CONFIG_PAGE_REPORTING=y -CONFIG_PARTITION_PERCPU=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_DOMAINS_GENERIC=y -CONFIG_PCI_ECAM=y -CONFIG_PCI_HOST_COMMON=y -CONFIG_PCI_HOST_GENERIC=y -CONFIG_PCI_MSI=y -CONFIG_PCI_MSI_IRQ_DOMAIN=y -CONFIG_PGTABLE_LEVELS=3 -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -CONFIG_RATIONAL=y -CONFIG_RFS_ACCEL=y -CONFIG_RPS=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_PL031=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_SCSI=y -CONFIG_SCSI_COMMON=y -CONFIG_SCSI_VIRTIO=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SG_POOL=y -CONFIG_SMP=y -CONFIG_SOCK_RX_QUEUE_MAPPING=y -CONFIG_SPARSE_IRQ=y -CONFIG_SRCU=y -CONFIG_SWIOTLB=y -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TREE_RCU=y -CONFIG_TREE_SRCU=y -CONFIG_USB_SUPPORT=y -CONFIG_VIRTIO=y -CONFIG_VIRTIO_BALLOON=y -CONFIG_VIRTIO_BLK=y -CONFIG_VIRTIO_CONSOLE=y -CONFIG_VIRTIO_MMIO=y -CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y -CONFIG_VIRTIO_NET=y -CONFIG_VIRTIO_PCI=y -CONFIG_VIRTIO_PCI_LEGACY=y -CONFIG_VIRTIO_PCI_LIB=y -CONFIG_XPS=y diff --git a/target/linux/ath25/patches-5.15/700-swconfig_mvswitch.patch b/target/linux/ath25/patches-5.15/700-swconfig_mvswitch.patch index 79a4d1c1a03..dcfc019f128 100644 --- a/target/linux/ath25/patches-5.15/700-swconfig_mvswitch.patch +++ b/target/linux/ath25/patches-5.15/700-swconfig_mvswitch.patch @@ -1,6 +1,6 @@ --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig -@@ -95,6 +95,10 @@ config IP17XX_PHY +@@ -96,6 +96,10 @@ config IP17XX_PHY tristate "Driver for IC+ IP17xx switches" select SWCONFIG diff --git a/target/linux/ath79/dts/qca9561_tplink_tl-wdr6500-v2.dts b/target/linux/ath79/dts/qca9561_tplink_tl-wdr6500-v2.dts new file mode 100644 index 00000000000..15c58686597 --- /dev/null +++ b/target/linux/ath79/dts/qca9561_tplink_tl-wdr6500-v2.dts @@ -0,0 +1,172 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca956x.dtsi" + +#include +#include + +/ { + compatible = "tplink,tl-wdr6500-v2", "qca,qca9561"; + model = "TP-Link TL-WDR6500 v2"; + + aliases { + led-boot = &led_system; + led-failsafe = &led_system; + led-running = &led_system; + led-upgrade = &led_system; + label-mac-device = ð1; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "Reset button"; + linux,code = ; + gpios = <&gpio 1 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + + lan4 { + label = "green:lan4"; + gpios = <&gpio 14 GPIO_ACTIVE_LOW>; + }; + + lan3 { + label = "green:lan3"; + gpios = <&gpio 15 GPIO_ACTIVE_LOW>; + }; + + lan2 { + label = "green:lan2"; + gpios = <&gpio 16 GPIO_ACTIVE_LOW>; + }; + + lan1 { + label = "green:lan1"; + gpios = <&gpio 17 GPIO_ACTIVE_LOW>; + }; + + wan { + label = "green:wan"; + gpios = <&gpio 18 GPIO_ACTIVE_LOW>; + }; + + led_system: system { + label = "white:system"; + gpios = <&gpio 21 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + }; +}; + +&spi { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <25000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x000000 0x010000>; + read-only; + + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_uboot_0fc00: macaddr@0fc00 { + reg = <0x0fc00 0x6>; + }; + }; + + partition@10000 { + compatible = "tplink,firmware"; + label = "firmware"; + reg = <0x010000 0x7e0000>; + }; + + partition@7f0000 { + label = "art"; + reg = <0x7f0000 0x010000>; + read-only; + + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + calibration_ath9k: calibration@1000 { + reg = <0x1000 0x440>; + }; + + calibration_ath10k: calibration@5000 { + reg = <0x5000 0x844>; + }; + }; + }; + }; +}; + +&uart { + status = "okay"; +}; + +&pcie { + status = "okay"; + + wifi@0,0 { + compatible = "qcom,ath10k"; + reg = <0 0 0 0 0>; + + nvmem-cells = <&macaddr_uboot_0fc00>, <&calibration_ath10k>; + nvmem-cell-names = "mac-address", "calibration"; + mac-address-increment = <(-2)>; + }; +}; + +&mdio0 { + status = "okay"; +}; + +ð0 { + status = "okay"; + + phy-handle = <&swphy4>; + + nvmem-cells = <&macaddr_uboot_0fc00>; + nvmem-cell-names = "mac-address"; + mac-address-increment = <1>; +}; + +ð1 { + status = "okay"; + + nvmem-cells = <&macaddr_uboot_0fc00>; + nvmem-cell-names = "mac-address"; +}; + +&wmac { + status = "okay"; + + nvmem-cells = <&macaddr_uboot_0fc00>, <&calibration_ath9k>; + nvmem-cell-names = "mac-address", "calibration"; + mac-address-increment = <(-1)>; +}; + +&usb0 { + status = "okay"; +}; + +&usb_phy0 { + status = "okay"; +}; diff --git a/target/linux/ath79/generic/base-files/etc/board.d/01_leds b/target/linux/ath79/generic/base-files/etc/board.d/01_leds index 2ee4ed2544d..10c67991fd2 100644 --- a/target/linux/ath79/generic/base-files/etc/board.d/01_leds +++ b/target/linux/ath79/generic/base-files/etc/board.d/01_leds @@ -30,6 +30,13 @@ tplink,cpe610-v2|\ tplink,tl-wa1201-v2) ucidef_set_led_netdev "lan" "LAN" "green:lan" "eth0" ;; +tplink,tl-wdr6500-v2) + ucidef_set_led_netdev "wan" "WAN" "green:wan" "eth1" + ucidef_set_led_switch "lan1" "LAN1" "green:lan1" "switch0" "0x02" + ucidef_set_led_switch "lan2" "LAN2" "green:lan2" "switch0" "0x04" + ucidef_set_led_switch "lan3" "LAN3" "green:lan3" "switch0" "0x08" + ucidef_set_led_switch "lan4" "LAN4" "green:lan4" "switch0" "0x10" + ;; alfa-network,n2q) ucidef_set_led_netdev "lan2" "LAN2" "orange:lan2" "eth1" ucidef_set_led_switch "lan1" "LAN1" "orange:lan1" "switch0" "0x10" diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network index 4f535f8a648..d18eddf5b74 100644 --- a/target/linux/ath79/generic/base-files/etc/board.d/02_network +++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network @@ -247,7 +247,8 @@ ath79_setup_interfaces() comfast,cf-e560ac|\ qca,ap143-8m|\ qca,ap143-16m|\ - tplink,tl-wr841hp-v3) + tplink,tl-wr841hp-v3|\ + tplink,tl-wdr6500-v2) ucidef_set_interface_wan "eth1" ucidef_add_switch "switch0" \ "0@eth0" "1:lan" "2:lan" "3:lan" "4:lan" diff --git a/target/linux/ath79/image/generic-tp-link.mk b/target/linux/ath79/image/generic-tp-link.mk index cfabc89b8df..460297e7e99 100644 --- a/target/linux/ath79/image/generic-tp-link.mk +++ b/target/linux/ath79/image/generic-tp-link.mk @@ -676,6 +676,22 @@ define Device/tplink_tl-wdr4900-v2 endef TARGET_DEVICES += tplink_tl-wdr4900-v2 +define Device/tplink_tl-wdr6500-v2 + $(Device/tplink-8mlzma) + SOC := qca9561 + DEVICE_MODEL := TL-WDR6500 + DEVICE_VARIANT := v2 + DEVICE_PACKAGES := kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev \ + kmod-ath9k kmod-ath10k-ct ath10k-firmware-qca988x-ct + IMAGE_SIZE := 8000k + KERNEL := kernel-bin | append-dtb | lzma | uImage lzma + KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | uImage lzma + TPLINK_HWID := 0x65000002 + TPLINK_HEADER_VERSION := 1 + SUPPORTED_DEVICES += tl-wdr6500-v2 +endef +TARGET_DEVICES += tplink_tl-wdr6500-v2 + define Device/tplink_tl-wdr7500-v3 $(Device/tplink-8mlzma) SOC := qca9558 diff --git a/target/linux/ath79/patches-5.15/910-unaligned_access_hacks.patch b/target/linux/ath79/patches-5.15/910-unaligned_access_hacks.patch index 88693d5f1ad..5c659b3d2ca 100644 --- a/target/linux/ath79/patches-5.15/910-unaligned_access_hacks.patch +++ b/target/linux/ath79/patches-5.15/910-unaligned_access_hacks.patch @@ -336,7 +336,7 @@ SVN-Revision: 35130 #endif /* _LINUX_TYPES_H */ --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c -@@ -1475,8 +1475,8 @@ struct sk_buff *inet_gro_receive(struct +@@ -1477,8 +1477,8 @@ struct sk_buff *inet_gro_receive(struct if (unlikely(ip_fast_csum((u8 *)iph, 5))) goto out_unlock; diff --git a/target/linux/bcm27xx/patches-6.1/950-0120-Added-Device-IDs-for-August-DVB-T-205.patch b/target/linux/bcm27xx/patches-6.1/950-0120-Added-Device-IDs-for-August-DVB-T-205.patch index ec8587f688f..a77f3f75b1e 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0120-Added-Device-IDs-for-August-DVB-T-205.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0120-Added-Device-IDs-for-August-DVB-T-205.patch @@ -9,7 +9,7 @@ Subject: [PATCH] Added Device IDs for August DVB-T 205 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c -@@ -1944,6 +1944,10 @@ static const struct usb_device_id rtl28x +@@ -1964,6 +1964,10 @@ static const struct usb_device_id rtl28x &rtl28xxu_props, "Compro VideoMate U650F", NULL) }, { DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd394, &rtl28xxu_props, "MaxMedia HU394-T", NULL) }, diff --git a/target/linux/bcm27xx/patches-6.1/950-0188-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch b/target/linux/bcm27xx/patches-6.1/950-0188-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch index df8f22265f3..2426a39ac37 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0188-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0188-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch @@ -33,7 +33,7 @@ Signed-off-by: Jonathan Bell #define USB_VENDOR_ID_BELKIN 0x050d #define USB_DEVICE_ID_FLIP_KVM 0x3201 -@@ -1366,6 +1369,9 @@ +@@ -1367,6 +1370,9 @@ #define USB_VENDOR_ID_XIAOMI 0x2717 #define USB_DEVICE_ID_MI_SILENT_MOUSE 0x5014 diff --git a/target/linux/bmips/bcm6328/base-files/etc/board.d/02_network b/target/linux/bmips/bcm6328/base-files/etc/board.d/02_network index 792926fcf27..c9c704067e9 100644 --- a/target/linux/bmips/bcm6328/base-files/etc/board.d/02_network +++ b/target/linux/bmips/bcm6328/base-files/etc/board.d/02_network @@ -5,6 +5,7 @@ board_config_update case "$(board_name)" in +comtrend,ar-5381u |\ comtrend,ar-5387un) ucidef_set_bridge_device switch ucidef_set_interface_lan "lan1 lan2 lan3 lan4" diff --git a/target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc b/target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc index 3909947be6d..21f18b4b819 100644 --- a/target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc +++ b/target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc @@ -3,6 +3,7 @@ . /lib/functions.sh case "$(board_name)" in +comtrend,ar-5381u |\ comtrend,ar-5387un) mtd fixtrx firmware ;; diff --git a/target/linux/bmips/bcm6368/base-files/etc/board.d/01_leds b/target/linux/bmips/bcm6368/base-files/etc/board.d/01_leds index ab797568b7f..c7e61fe72f3 100644 --- a/target/linux/bmips/bcm6368/base-files/etc/board.d/01_leds +++ b/target/linux/bmips/bcm6368/base-files/etc/board.d/01_leds @@ -6,6 +6,23 @@ board_config_update case "$(board_name)" in +comtrend,wap-5813n) + ucidef_set_led_usbport "usb" "USB" "green:usb" "usb1-port1" "usb2-port1" + ;; +netgear,dgnd3700-v1 |\ +netgear,dgnd3800b) + ucidef_set_led_netdev "lan" "LAN" "green:lan" "switch.1" + ucidef_set_led_netdev "wan" "WAN" "green:wan" "wan" + ucidef_set_led_netdev "wlan0" "WIFI2G" "green:wifi2g" "phy0-ap0" + ucidef_set_led_netdev "wlan1" "WIFI5G" "blue:wifi5g" "phy1-ap0" + ucidef_set_led_usbport "usb1" "USB1" "green:usb1" "usb1-port1" "usb2-port1" + ucidef_set_led_usbport "usb2" "USB2" "green:usb2" "usb1-port2" "usb2-port2" + ;; +netgear,evg2000) + ucidef_set_led_netdev "lan" "LAN" "green:lan" "switch.1" + ucidef_set_led_netdev "wan" "WAN" "green:wan" "wan" + ucidef_set_led_usbdev "usb" "USB" "green:usb" "usb1-port1" "usb2-port1" "usb1-port2" "usb2-port2" + ;; observa,vh4032n) ucidef_set_led_usbport "usb1" "USB1" "blue:hspa" "usb1-port1" "usb2-port1" ucidef_set_led_usbport "usb2" "USB2" "red:hspa" "1-2-port1" "1-2-port2" diff --git a/target/linux/bmips/bcm6368/base-files/etc/board.d/02_network b/target/linux/bmips/bcm6368/base-files/etc/board.d/02_network index 1064b80fba1..58fba05fec3 100644 --- a/target/linux/bmips/bcm6368/base-files/etc/board.d/02_network +++ b/target/linux/bmips/bcm6368/base-files/etc/board.d/02_network @@ -10,6 +10,17 @@ observa,vh4032n) ucidef_set_bridge_device switch ucidef_set_interface_lan "lan1 lan2 lan3 lan4" ;; +comtrend,vr-3025un) + ucidef_set_bridge_device switch + ucidef_set_interface_lan "lan1 lan2 lan3 iptv" + ;; +comtrend,wap-5813n |\ +netgear,dgnd3700-v1 |\ +netgear,dgnd3800b |\ +netgear,evg2000) + ucidef_set_bridge_device switch + ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "wan" + ;; esac board_config_flush diff --git a/target/linux/bmips/bcm6368/base-files/etc/uci-defaults/09_fix_crc b/target/linux/bmips/bcm6368/base-files/etc/uci-defaults/09_fix_crc index d4ff723d142..63d10c9a8e8 100644 --- a/target/linux/bmips/bcm6368/base-files/etc/uci-defaults/09_fix_crc +++ b/target/linux/bmips/bcm6368/base-files/etc/uci-defaults/09_fix_crc @@ -4,6 +4,9 @@ case "$(board_name)" in comtrend,vr-3025u |\ +comtrend,vr-3025un |\ +comtrend,wap-5813n |\ +netgear,evg2000 |\ observa,vh4032n) mtd fixtrx firmware ;; diff --git a/target/linux/bmips/dts/bcm63167-sercomm-h500-s.dtsi b/target/linux/bmips/dts/bcm63167-sercomm-h500-s.dtsi index 8e0024a20f5..95f330d6c53 100644 --- a/target/linux/bmips/dts/bcm63167-sercomm-h500-s.dtsi +++ b/target/linux/bmips/dts/bcm63167-sercomm-h500-s.dtsi @@ -8,10 +8,6 @@ led-failsafe = &led_power_red; led-running = &led_power_green; led-upgrade = &led_power_green; - - led-internet = &led_internet_green; - led-usb = &led_mobile_green; - led-wireless = &led_wireless_green; }; keys { @@ -56,7 +52,7 @@ label = "red:mobile"; }; - led_mobile_green: led@1 { + led@1 { reg = <1>; label = "green:mobile"; }; @@ -64,9 +60,10 @@ led_power_red: led@8 { reg = <8>; label = "red:power"; + panic-indicator; }; - led_wireless_green: led@9 { + led@9 { reg = <9>; label = "green:wifi"; }; @@ -86,7 +83,7 @@ label = "red:internet"; }; - led_internet_green: led@15 { + led@15 { reg = <15>; label = "green:internet"; }; diff --git a/target/linux/bmips/dts/bcm63168-comtrend-vr-3032u.dts b/target/linux/bmips/dts/bcm63168-comtrend-vr-3032u.dts index 8c4611ee881..5196f90afa8 100644 --- a/target/linux/bmips/dts/bcm63168-comtrend-vr-3032u.dts +++ b/target/linux/bmips/dts/bcm63168-comtrend-vr-3032u.dts @@ -11,10 +11,6 @@ led-failsafe = &led_power_green; led-running = &led_power_green; led-upgrade = &led_power_green; - - led-dsl = &led_dsl_green; - led-internet = &led_internet_green; - led-usb = &led_usb_green; }; keys { @@ -78,13 +74,13 @@ label = "red:internet"; }; - led_dsl_green: led@3 { + led@3 { reg = <3>; active-low; label = "green:dsl"; }; - led_usb_green: led@4 { + led@4 { reg = <4>; active-low; label = "green:usb"; @@ -96,7 +92,7 @@ label = "green:wps"; }; - led_internet_green: led@8 { + led@8 { reg = <8>; active-low; label = "green:internet"; diff --git a/target/linux/bmips/dts/bcm63168-sercomm-shg2500.dts b/target/linux/bmips/dts/bcm63168-sercomm-shg2500.dts index bb769b09e1c..7b0ebf2aefc 100644 --- a/target/linux/bmips/dts/bcm63168-sercomm-shg2500.dts +++ b/target/linux/bmips/dts/bcm63168-sercomm-shg2500.dts @@ -11,10 +11,6 @@ led-failsafe = &led_power_red; led-running = &led_power_red; led-upgrade = &led_power_red; - - led-internet = &led_internet_green; - led-usb = &led_modem_green; - led-wireless = &led_wireless_green; }; i2c { @@ -82,7 +78,7 @@ label = "red:modem"; }; - led_modem_green: led@2 { + led@2 { reg = <2>; label = "green:modem"; }; @@ -107,7 +103,7 @@ label = "green:phone"; }; - led_wireless_green: led@7 { + led@7 { reg = <7>; label = "green:wifi"; }; @@ -117,7 +113,7 @@ label = "red:power"; }; - led_internet_green: led@9 { + led@9 { reg = <9>; label = "green:internet"; }; diff --git a/target/linux/bmips/dts/bcm6318-comtrend-ar-5315u.dts b/target/linux/bmips/dts/bcm6318-comtrend-ar-5315u.dts index 8ac37be495c..45ed6e2a3b7 100644 --- a/target/linux/bmips/dts/bcm6318-comtrend-ar-5315u.dts +++ b/target/linux/bmips/dts/bcm6318-comtrend-ar-5315u.dts @@ -11,10 +11,6 @@ led-failsafe = &led_power_red; led-running = &led_power_green; led-upgrade = &led_power_green; - - led-dsl = &led_dsl_green; - led-internet = &led_internet_green; - led-usb = &led_usb_green; }; keys { @@ -130,41 +126,41 @@ label = "green:power"; }; - led_usb_green: led@2 { + led@2 { reg = <2>; active-low; label = "green:usb"; }; led@4 { + /* EPHY0 Act */ reg = <4>; brcm,hardware-controlled; brcm,link-signal-sources = <4>; - /* EPHY0 Act */ }; led@5 { + /* EPHY1 Act */ reg = <5>; brcm,hardware-controlled; brcm,link-signal-sources = <5>; - /* EPHY1 Act */ }; led@6 { + /* EPHY2 Act */ reg = <6>; brcm,hardware-controlled; brcm,link-signal-sources = <6>; - /* EPHY2 Act */ }; led@7 { + /* EPHY3 Act */ reg = <7>; brcm,hardware-controlled; brcm,link-signal-sources = <7>; - /* EPHY3 Act */ }; - led_internet_green: led@8 { + led@8 { reg = <8>; active-low; label = "green:internet"; @@ -176,7 +172,7 @@ label = "red:internet"; }; - led_dsl_green: led@10 { + led@10 { reg = <10>; active-low; label = "green:dsl"; @@ -186,6 +182,7 @@ reg = <11>; active-low; label = "red:power"; + panic-indicator; }; }; diff --git a/target/linux/bmips/dts/bcm6328-comtrend-ar-5381u.dts b/target/linux/bmips/dts/bcm6328-comtrend-ar-5381u.dts new file mode 100644 index 00000000000..7499e7090ff --- /dev/null +++ b/target/linux/bmips/dts/bcm6328-comtrend-ar-5381u.dts @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "bcm6328.dtsi" + +/ { + model = "Comtrend AR-5381u"; + compatible = "comtrend,ar-5381u", "brcm,bcm6328"; + + aliases { + led-boot = &led_power_green; + led-failsafe = &led_alarm_red; + led-running = &led_power_green; + led-upgrade = &led_power_green; + }; + + keys { + compatible = "gpio-keys-polled"; + poll-interval = <100>; + + reset { + label = "reset"; + gpios = <&gpio 23 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <60>; + }; + }; + + bcm43225-sprom { + compatible = "brcm,bcma-sprom"; + + pci-bus = <1>; + pci-dev = <0>; + + nvmem-cells = <&macaddr_cfe_6a0>; + nvmem-cell-names = "mac-address"; + mac-address-increment = <1>; + + brcm,sprom = "brcm/bcm43225-sprom.bin"; + brcm,sprom-fixups = <97 0xfee5>, + <98 0x157c>, + <99 0xfae7>, + <113 0xfefa>, + <114 0x15d6>, + <115 0xfaf8>; + }; +}; + +&ehci { + status = "okay"; +}; + +ðernet { + status = "okay"; + + nvmem-cells = <&macaddr_cfe_6a0>; + nvmem-cell-names = "mac-address"; +}; + +&hsspi { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <16666667>; + spi-tx-bus-width = <2>; + spi-rx-bus-width = <2>; + reg = <0>; + + #address-cells = <1>; + #size-cells = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + cfe: partition@0 { + reg = <0x000000 0x010000>; + label = "cfe"; + read-only; + }; + + partition@10000 { + compatible = "brcm,bcm963xx-imagetag"; + reg = <0x010000 0xfe0000>; + label = "firmware"; + }; + + partition@ff0000 { + reg = <0xff0000 0x010000>; + label = "nvram"; + }; + }; + }; +}; + +&leds { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_leds>; + + led_alarm_red: led@2 { + reg = <2>; + active-low; + label = "red:alarm"; + panic-indicator; + }; + + led@3 { + reg = <3>; + active-low; + label = "green:internet"; + }; + + led_power_green: led@4 { + reg = <4>; + active-low; + label = "green:power"; + }; +}; + +&ohci { + status = "okay"; +}; + +&pcie { + status = "okay"; +}; + +&pinctrl { + pinctrl_leds: leds { + function = "led"; + pins = "gpio2", "gpio3", "gpio4"; + }; +}; + +&switch0 { + ports { + port@0 { + reg = <0>; + label = "lan1"; + + phy-handle = <&phy1>; + phy-mode = "mii"; + }; + + port@1 { + reg = <1>; + label = "lan2"; + + phy-handle = <&phy2>; + phy-mode = "mii"; + }; + + port@2 { + reg = <2>; + label = "lan3"; + + phy-handle = <&phy3>; + phy-mode = "mii"; + }; + + port@3 { + reg = <3>; + label = "lan4"; + + phy-handle = <&phy4>; + phy-mode = "mii"; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&usbh { + status = "okay"; +}; + +&cfe { + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_cfe_6a0: macaddr@6a0 { + reg = <0x6a0 0x6>; + }; +}; diff --git a/target/linux/bmips/dts/bcm6328-comtrend-ar-5387un.dts b/target/linux/bmips/dts/bcm6328-comtrend-ar-5387un.dts index 72802366a08..a0d1c117f74 100644 --- a/target/linux/bmips/dts/bcm6328-comtrend-ar-5387un.dts +++ b/target/linux/bmips/dts/bcm6328-comtrend-ar-5387un.dts @@ -11,9 +11,6 @@ led-failsafe = &led_power_red; led-running = &led_power_green; led-upgrade = &led_power_green; - - led-dsl = &led_dsl_green; - led-internet = &led_internet_green; }; keys { @@ -129,9 +126,10 @@ led_power_red: led@4 { reg = <4>; label = "red:power"; + panic-indicator; }; - led_internet_green: led@7 { + led@7 { reg = <7>; label = "green:internet"; }; @@ -141,7 +139,7 @@ label = "green:power"; }; - led_dsl_green: led@11 { + led@11 { reg = <11>; active-low; label = "green:dsl"; diff --git a/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts b/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts index 716c6227f8a..d5f162846d2 100644 --- a/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts +++ b/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts @@ -3,17 +3,14 @@ #include "bcm6358.dtsi" / { - compatible = "huawei,hg556a-b", "brcm,bcm6358"; model = "Huawei EchoLife HG556a (version B)"; + compatible = "huawei,hg556a-b", "brcm,bcm6358"; aliases { led-boot = &led_power_red; led-failsafe = &led_power_red; led-running = &led_power_red; led-upgrade = &led_power_red; - - led-dsl = &led_dsl_red; - led-usb = &led_hspa_red; }; keys { @@ -57,12 +54,12 @@ gpios = <&gpio 0 GPIO_ACTIVE_LOW>; }; - led_hspa_red: led@1 { + led@1 { label = "red:hspa"; gpios = <&gpio 1 GPIO_ACTIVE_LOW>; }; - led_dsl_red: led@2 { + led@2 { label = "red:dsl"; gpios = <&gpio 2 GPIO_ACTIVE_LOW>; }; diff --git a/target/linux/bmips/dts/bcm6362-huawei-hg253s-v2.dts b/target/linux/bmips/dts/bcm6362-huawei-hg253s-v2.dts index 2a9a6c559a7..f562bcd9b2b 100644 --- a/target/linux/bmips/dts/bcm6362-huawei-hg253s-v2.dts +++ b/target/linux/bmips/dts/bcm6362-huawei-hg253s-v2.dts @@ -10,10 +10,6 @@ led-boot = &led_phone_green; led-failsafe = &led_phone_green; led-upgrade = &led_phone_green; - - led-internet = &led_internet_green; - led-usb = &led_usb_green; - led-wireless = &led_wireless_green; }; keys { @@ -50,7 +46,7 @@ gpios = <&gpio 28 GPIO_ACTIVE_LOW>; }; - led_usb_green: led@30 { + led@30 { label = "green:usb"; gpios = <&gpio 30 GPIO_ACTIVE_LOW>; }; @@ -74,13 +70,13 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_leds>; - led_internet_green: led@3 { + led@3 { reg = <3>; active-low; label = "green:internet"; }; - led_wireless_green: led@5 { + led@5 { reg = <5>; active-low; label = "green:wifi"; diff --git a/target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts b/target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts index ddcde2b6889..46bb3e8bf65 100644 --- a/target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts +++ b/target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts @@ -11,12 +11,6 @@ led-failsafe = &led_power_red; led-running = &led_power_green; led-upgrade = &led_power_green; - - led-dsl = &led_dsl_green; - led-ethernet = &led_ethernet_green; - led-internet = &led_internet_green; - led-usb = &led_usb1_green; - led-usb2 = &led_usb2_green; }; keys { @@ -48,7 +42,7 @@ leds { compatible = "gpio-leds"; - led_dsl_green: led@28 { + led@28 { label = "green:dsl"; gpios = <&gpio 28 GPIO_ACTIVE_LOW>; }; @@ -56,6 +50,7 @@ led_power_red: led@34 { label = "red:power"; gpios = <&gpio 34 GPIO_ACTIVE_LOW>; + panic-indicator; }; }; }; @@ -82,7 +77,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_leds &pinctrl_serial_led>; - led_internet_green: led@1 { + led@1 { reg = <1>; active-low; label = "green:internet"; @@ -99,13 +94,13 @@ label = "green:wps"; }; - led_usb1_green: led@10 { + led@10 { reg = <10>; active-low; label = "green:usb1"; }; - led_usb2_green: led@11 { + led@11 { reg = <11>; active-low; label = "green:usb2"; @@ -117,7 +112,7 @@ label = "amber:internet"; }; - led_ethernet_green: led@13 { + led@13 { reg = <13>; active-low; label = "green:ethernet"; diff --git a/target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts b/target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts index 60029fe7f84..e67db8b6bde 100644 --- a/target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts +++ b/target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts @@ -11,9 +11,6 @@ led-failsafe = &led_power_red; led-running = &led_power_green; led-upgrade = &led_power_green; - - led-dsl = &led_dsl_green; - led-internet = &led_internet_green; }; keys { @@ -31,12 +28,12 @@ leds { compatible = "gpio-leds"; - led_dsl_green: led@2 { + led@2 { label = "green:dsl"; gpios = <&gpio 2 GPIO_ACTIVE_LOW>; }; - led_internet_green: led@5 { + led@5 { label = "green:internet"; gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; }; @@ -49,6 +46,7 @@ led_power_red: led@24 { label = "red:power"; gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; + panic-indicator; }; led@31 { diff --git a/target/linux/bmips/dts/bcm6368-comtrend-vr-3025un.dts b/target/linux/bmips/dts/bcm6368-comtrend-vr-3025un.dts new file mode 100644 index 00000000000..3256783e0e8 --- /dev/null +++ b/target/linux/bmips/dts/bcm6368-comtrend-vr-3025un.dts @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "bcm6368.dtsi" + +/ { + model = "Comtrend VR-3025un"; + compatible = "comtrend,vr-3025un", "brcm,bcm6368"; + + aliases { + led-boot = &led_power_green; + led-failsafe = &led_power_red; + led-running = &led_power_green; + led-upgrade = &led_power_green; + }; + + keys { + compatible = "gpio-keys-polled"; + poll-interval = <100>; + + reset { + label = "reset"; + gpios = <&gpio 34 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <60>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led@2 { + label = "green:dsl"; + gpios = <&gpio 2 GPIO_ACTIVE_LOW>; + }; + + led@5 { + label = "green:internet"; + gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; + }; + + led_power_green: led@22 { + label = "green:power"; + gpios = <&gpio 22 GPIO_ACTIVE_HIGH>; + }; + + led_power_red: led@24 { + label = "red:power"; + gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; + panic-indicator; + }; + + led@31 { + label = "red:internet"; + gpios = <&gpio 31 GPIO_ACTIVE_HIGH>; + }; + }; + + bcm43222-sprom { + compatible = "brcm,ssb-sprom"; + + pci-bus = <0>; + pci-dev = <1>; + + nvmem-cells = <&macaddr_cfe_6a0>; + nvmem-cell-names = "mac-address"; + mac-address-increment = <1>; + + brcm,sprom = "brcm/bcm43222-sprom.bin"; + brcm,sprom-fixups = <97 0xfeb3>, + <98 0x1618>, + <99 0xfab0>, + <113 0xfed1>, + <114 0x1609>, + <115 0xfad9>; + }; +}; + +&ehci { + status = "okay"; +}; + +ðernet { + status = "okay"; + + nvmem-cells = <&macaddr_cfe_6a0>; + nvmem-cell-names = "mac-address"; +}; + +&ohci { + status = "okay"; +}; + +&pci { + status = "okay"; +}; + +&pflash { + status = "okay"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + cfe: partition@0 { + label = "CFE"; + reg = <0x000000 0x010000>; + read-only; + }; + + partition@20000 { + compatible = "brcm,bcm963xx-imagetag"; + label = "firmware"; + reg = <0x010000 0x7e0000>; + }; + + partition@1fe0000 { + label = "nvram"; + reg = <0x7f0000 0x010000>; + }; + }; +}; + +&pinctrl { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ephy0_led &pinctrl_ephy1_led + &pinctrl_ephy2_led &pinctrl_ephy3_led>; +}; + +&switch0 { + ports { + port@0 { + reg = <0>; + label = "lan1"; + + phy-handle = <&phy1>; + phy-mode = "mii"; + }; + + port@1 { + reg = <1>; + label = "lan2"; + + phy-handle = <&phy2>; + phy-mode = "mii"; + }; + + port@2 { + reg = <2>; + label = "lan3"; + + phy-handle = <&phy3>; + phy-mode = "mii"; + }; + + port@3 { + reg = <3>; + label = "iptv"; + + phy-handle = <&phy4>; + phy-mode = "mii"; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&usbh { + status = "okay"; +}; + +&cfe { + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_cfe_6a0: macaddr@6a0 { + reg = <0x6a0 0x6>; + }; +}; diff --git a/target/linux/bmips/dts/bcm6368-netgear-dgnd3700-v1.dts b/target/linux/bmips/dts/bcm6368-netgear-dgnd3700-v1.dts new file mode 100644 index 00000000000..4ec6c480834 --- /dev/null +++ b/target/linux/bmips/dts/bcm6368-netgear-dgnd3700-v1.dts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "bcm6368-netgear-dgnd3700.dtsi" + +/ { + model = "Netgear DGND3700 v1"; + compatible = "netgear,dgnd3700-v1", "brcm,bcm6368"; +}; diff --git a/target/linux/bmips/dts/bcm6368-netgear-dgnd3700.dtsi b/target/linux/bmips/dts/bcm6368-netgear-dgnd3700.dtsi new file mode 100644 index 00000000000..74494556310 --- /dev/null +++ b/target/linux/bmips/dts/bcm6368-netgear-dgnd3700.dtsi @@ -0,0 +1,265 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "bcm6368.dtsi" + +/ { + aliases { + led-boot = &led_power_green; + led-failsafe = &led_power_red; + led-running = &led_power_green; + led-upgrade = &led_power_green; + }; + + keys { + compatible = "gpio-keys-polled"; + poll-interval = <100>; + + rfkill { + label = "rfkill"; + gpios = <&gpio 10 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <60>; + }; + + reset { + label = "reset"; + gpios = <&gpio 12 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <60>; + }; + + wps { + label = "wps"; + gpios = <&gpio 35 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <60>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led@2 { + label = "green:dsl"; + gpios = <&gpio 2 GPIO_ACTIVE_LOW>; + }; + + led@4 { + label = "red:wan"; + gpios = <&gpio 4 GPIO_ACTIVE_LOW>; + }; + + led@5 { + label = "green:wan"; + gpios = <&gpio 5 GPIO_ACTIVE_LOW>; + }; + + led@11 { + label = "green:wps"; + gpios = <&gpio 11 GPIO_ACTIVE_LOW>; + }; + + led@13 { + /* Front USB port */ + label = "green:usb2"; + gpios = <&gpio 13 GPIO_ACTIVE_LOW>; + }; + + led@14 { + /* Back USB port */ + label = "green:usb1"; + gpios = <&gpio 14 GPIO_ACTIVE_LOW>; + }; + + led_power_red: led@22 { + label = "red:power"; + gpios = <&gpio 22 GPIO_ACTIVE_LOW>; + panic-indicator; + }; + + led@23 { + label = "green:lan"; + gpios = <&gpio 23 GPIO_ACTIVE_LOW>; + }; + + led_power_green: led@24 { + label = "green:power"; + gpios = <&gpio 24 GPIO_ACTIVE_LOW>; + }; + + led@26 { + label = "green:wifi2g"; + gpios = <&gpio 26 GPIO_ACTIVE_LOW>; + }; + + led@27 { + label = "blue:wifi5g"; + gpios = <&gpio 27 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&ehci { + status = "okay"; +}; + +ðernet { + status = "okay"; + + nvmem-cells = <&macaddr_cfe_6a0>; + nvmem-cell-names = "mac-address"; +}; + +&lsspi { + status = "okay"; + + switch@1 { + compatible = "brcm,bcm53115"; + reg = <1>; + spi-max-frequency = <781000>; + dsa,member = <1 0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + wan@0 { + reg = <0>; + label = "wan"; + }; + + port@1 { + reg = <1>; + label = "lan4"; + }; + + port@2 { + reg = <2>; + label = "lan3"; + }; + + port@3 { + reg = <3>; + label = "lan2"; + }; + + port@4 { + reg = <4>; + label = "lan1"; + }; + + port@8 { + reg = <8>; + + phy-mode = "rgmii"; + ethernet = <&switch0port5>; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; +}; + +&nflash { + status = "okay"; + + nandcs@0 { + compatible = "brcm,nandcs"; + reg = <0>; + nand-ecc-step-size = <512>; + nand-ecc-strength = <15>; + nand-on-flash-bbt; + brcm,nand-oob-sector-size = <64>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "storage"; + reg = <0 0>; /* autodetected size */ + }; + }; + }; +}; + +&ohci { + status = "okay"; +}; + +&pci { + status = "okay"; +}; + +&pflash { + status = "okay"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + cfe: partition@0 { + label = "CFE"; + reg = <0x0000000 0x0020000>; + read-only; + }; + + partition@20000 { + compatible = "brcm,bcm963xx-imagetag"; + label = "firmware"; + reg = <0x0020000 0x1e20000>; + }; + + partition@1e40000 { + label = "board_data"; + reg = <0x1e40000 0x1a0000>; + read-only; + }; + + partition@1fe0000 { + label = "nvram"; + reg = <0x1fe0000 0x020000>; + }; + }; +}; + +&switch0 { + dsa,member = <0 0>; + + ports { + switch0port5: port@5 { + reg = <5>; + label = "extsw"; + + phy-mode = "rgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&usbh { + status = "okay"; +}; + +&cfe { + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_cfe_6a0: macaddr@6a0 { + reg = <0x6a0 0x6>; + }; +}; diff --git a/target/linux/bmips/dts/bcm6368-netgear-dgnd3800b.dts b/target/linux/bmips/dts/bcm6368-netgear-dgnd3800b.dts new file mode 100644 index 00000000000..350d3619c05 --- /dev/null +++ b/target/linux/bmips/dts/bcm6368-netgear-dgnd3800b.dts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "bcm6368-netgear-dgnd3700.dtsi" + +/ { + model = "Netgear DGND3800B"; + compatible = "netgear,dgnd3800b", "brcm,bcm6368"; +}; diff --git a/target/linux/bmips/dts/bcm6368-observa-vh4032n.dts b/target/linux/bmips/dts/bcm6368-observa-vh4032n.dts index 4a4cca0982c..14fbd856f8f 100644 --- a/target/linux/bmips/dts/bcm6368-observa-vh4032n.dts +++ b/target/linux/bmips/dts/bcm6368-observa-vh4032n.dts @@ -58,12 +58,12 @@ led_power_blue: led@22 { label = "blue:power"; gpios = <&gpio 22 GPIO_ACTIVE_HIGH>; - default-state = "on"; }; led_power_red: led@24 { label = "red:power"; gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; + panic-indicator; }; led@25 { diff --git a/target/linux/bmips/dts/bcm6369-comtrend-wap-5813n.dts b/target/linux/bmips/dts/bcm6369-comtrend-wap-5813n.dts new file mode 100644 index 00000000000..517a894cf50 --- /dev/null +++ b/target/linux/bmips/dts/bcm6369-comtrend-wap-5813n.dts @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "bcm6368.dtsi" + +/ { + model = "Comtrend WAP-5813n"; + compatible = "comtrend,wap-5813n", "brcm,bcm6369", "brcm,bcm6368"; + + aliases { + led-boot = &led_power_green; + led-failsafe = &led_power_red; + led-running = &led_power_green; + led-upgrade = &led_power_green; + }; + + keys { + compatible = "gpio-keys-polled"; + poll-interval = <100>; + + wlan { + label = "wlan"; + gpios = <&gpio 32 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <60>; + }; + + reset { + label = "reset"; + gpios = <&gpio 34 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <60>; + }; + + wps { + label = "wps"; + gpios = <&gpio 35 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <60>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led@5 { + label = "green:internet"; + gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; + }; + + led@14 { + label = "green:usb"; + gpios = <&gpio 14 GPIO_ACTIVE_LOW>; + }; + + led_power_green: led@22 { + label = "green:power"; + gpios = <&gpio 22 GPIO_ACTIVE_HIGH>; + }; + + led@23 { + label = "green:wps"; + gpios = <&gpio 23 GPIO_ACTIVE_LOW>; + }; + + led_power_red: led@24 { + label = "red:power"; + gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; + panic-indicator; + }; + + led@31 { + label = "red:internet"; + gpios = <&gpio 31 GPIO_ACTIVE_HIGH>; + }; + }; + + bcm4322-sprom { + compatible = "brcm,ssb-sprom"; + + pci-bus = <0>; + pci-dev = <1>; + + nvmem-cells = <&macaddr_cfe_6a0>; + nvmem-cell-names = "mac-address"; + mac-address-increment = <1>; + + brcm,sprom = "brcm/bcm4322-sprom.bin"; + brcm,sprom-fixups = <97 0xfeed>, + <98 0x15d1>, + <99 0xfb0d>, + <113 0xfef7>, + <114 0x15f7>, + <115 0xfb1a>; + }; +}; + +&ehci { + status = "okay"; +}; + +ðernet { + status = "okay"; + + nvmem-cells = <&macaddr_cfe_6a0>; + nvmem-cell-names = "mac-address"; +}; + +&lsspi { + status = "okay"; + + switch@0 { + compatible = "brcm,bcm53115"; + reg = <0>; + spi-max-frequency = <781000>; + dsa,member = <1 0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "lan4"; + }; + + port@1 { + reg = <1>; + label = "lan3"; + }; + + port@2 { + reg = <2>; + label = "lan2"; + }; + + port@3 { + reg = <3>; + label = "lan1"; + }; + + port@4 { + reg = <4>; + label = "wan"; + }; + + port@5 { + reg = <5>; + + phy-mode = "rgmii"; + ethernet = <&switch0port4>; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; +}; + +&pflash { + status = "okay"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + cfe: partition@0 { + label = "CFE"; + reg = <0x000000 0x010000>; + read-only; + }; + + partition@20000 { + label = "firmware"; + reg = <0x010000 0x7e0000>; + compatible = "brcm,bcm963xx-imagetag"; + }; + + partition@fe0000 { + label = "nvram"; + reg = <0x7f0000 0x010000>; + }; + }; +}; + +&ohci { + status = "okay"; +}; + +&pci { + status = "okay"; +}; + +&switch0 { + dsa,member = <0 0>; + + ports { + switch0port4: port@4 { + reg = <4>; + label = "extsw"; + + phy-mode = "rgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&usbh { + status = "okay"; +}; + +&cfe { + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_cfe_6a0: macaddr@6a0 { + reg = <0x6a0 0x6>; + }; +}; diff --git a/target/linux/bmips/dts/bcm6369-netgear-evg2000.dts b/target/linux/bmips/dts/bcm6369-netgear-evg2000.dts new file mode 100644 index 00000000000..460c88f755c --- /dev/null +++ b/target/linux/bmips/dts/bcm6369-netgear-evg2000.dts @@ -0,0 +1,237 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "bcm6368.dtsi" + +/ { + model = "Netgear EVG2000"; + compatible = "netgear,evg2000", "brcm,bcm6369", "brcm,bcm6368"; + + aliases { + led-boot = &led_power_green; + led-failsafe = &led_power_red; + led-running = &led_power_green; + led-upgrade = &led_power_green; + }; + + keys { + compatible = "gpio-keys-polled"; + poll-interval = <100>; + + reset { + label = "reset"; + gpios = <&gpio 25 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <60>; + }; + + wps { + label = "wps"; + gpios = <&gpio 26 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <60>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led@2 { + label = "green:voip2"; + gpios = <&gpio 2 GPIO_ACTIVE_LOW>; + }; + + led@4 { + label = "red:internet"; + gpios = <&gpio 4 GPIO_ACTIVE_LOW>; + }; + + led@5 { + label = "green:internet"; + gpios = <&gpio 5 GPIO_ACTIVE_LOW>; + }; + + led@14 { + label = "green:voip1"; + gpios = <&gpio 14 GPIO_ACTIVE_LOW>; + }; + + led@15 { + label = "green:usb"; + gpios = <&gpio 15 GPIO_ACTIVE_LOW>; + }; + + led_power_green: led@22 { + label = "green:power"; + gpios = <&gpio 22 GPIO_ACTIVE_LOW>; + }; + + led_power_red: led@23 { + label = "red:power"; + gpios = <&gpio 23 GPIO_ACTIVE_LOW>; + panic-indicator; + }; + + led@24 { + label = "green:lan"; + gpios = <&gpio 24 GPIO_ACTIVE_LOW>; + }; + + led@27 { + label = "green:wan"; + gpios = <&gpio 27 GPIO_ACTIVE_LOW>; + }; + }; + + bcm4322-sprom { + compatible = "brcm,ssb-sprom"; + + pci-bus = <0>; + pci-dev = <1>; + + nvmem-cells = <&macaddr_cfe_6a0>; + nvmem-cell-names = "mac-address"; + mac-address-increment = <1>; + + brcm,sprom = "brcm/bcm4322-sprom.bin"; + brcm,sprom-fixups = <219 0xec08>; + }; +}; + +&ehci { + status = "okay"; +}; + +ðernet { + status = "okay"; + + nvmem-cells = <&macaddr_cfe_6a0>; + nvmem-cell-names = "mac-address"; +}; + +&mdio_ext { + switch@1e { + compatible = "brcm,bcm53115"; + reg = <30>; + + dsa,member = <1 0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "wan"; + }; + + port@1 { + reg = <1>; + label = "lan1"; + }; + + port@2 { + reg = <2>; + label = "lan2"; + }; + + port@3 { + reg = <3>; + label = "lan3"; + }; + + port@4 { + reg = <4>; + label = "lan4"; + }; + + port@8 { + reg = <8>; + + phy-mode = "rgmii"; + ethernet = <&switch0port5>; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; +}; + +&switch0 { + dsa,member = <0 0>; + + ports { + switch0port5: port@5 { + reg = <5>; + label = "extsw"; + + phy-mode = "rgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; +}; + +&pflash { + status = "okay"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + cfe: partition@0 { + label = "CFE"; + reg = <0x000000 0x020000>; + read-only; + }; + + partition@20000 { + label = "firmware"; + reg = <0x020000 0xf40000>; + compatible = "brcm,bcm963xx-imagetag"; + }; + + partition@f60000 { + label = "board_data"; + reg = <0xf60000 0x080000>; + read-only; + }; + + partition@fe0000 { + label = "nvram"; + reg = <0xfe0000 0x020000>; + }; + }; +}; + +&ohci { + status = "okay"; +}; + +&pci { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&usbh { + status = "okay"; +}; + +&cfe { + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_cfe_6a0: macaddr@6a0 { + reg = <0x6a0 0x6>; + }; +}; diff --git a/target/linux/bmips/image/Makefile b/target/linux/bmips/image/Makefile index b5e3098fe75..5ce026c5842 100644 --- a/target/linux/bmips/image/Makefile +++ b/target/linux/bmips/image/Makefile @@ -313,6 +313,15 @@ define Device/bcm63xx-nand DEVICE_PACKAGES += nand-utils endef +define Device/bcm63xx-netgear + $(Device/bcm63xx-cfe) + DEVICE_VENDOR := NETGEAR + IMAGES := factory.chk sysupgrade.bin + IMAGE/factory.chk := cfe-bin | netgear-chk + NETGEAR_BOARD_ID := + NETGEAR_REGION := +endef + define Device/sercomm-nand $(Device/bcm63xx-nand) IMAGES := factory.img sysupgrade.bin diff --git a/target/linux/bmips/image/bcm6328.mk b/target/linux/bmips/image/bcm6328.mk index b3cef51a71b..dfa134df946 100644 --- a/target/linux/bmips/image/bcm6328.mk +++ b/target/linux/bmips/image/bcm6328.mk @@ -1,5 +1,18 @@ # SPDX-License-Identifier: GPL-2.0-or-later +define Device/comtrend_ar-5381u + $(Device/bcm63xx-cfe) + DEVICE_VENDOR := Comtrend + DEVICE_MODEL := AR-5381u + CHIP_ID := 6328 + CFE_BOARD_ID := 96328A-1241N + FLASH_MB := 16 + DEVICE_PACKAGES += $(USB2_PACKAGES) \ + $(B43_PACKAGES) broadcom-43225-sprom \ + kmod-leds-bcm6328 +endef +TARGET_DEVICES += comtrend_ar-5381u + define Device/comtrend_ar-5387un $(Device/bcm63xx-cfe) DEVICE_VENDOR := Comtrend diff --git a/target/linux/bmips/image/bcm6368.mk b/target/linux/bmips/image/bcm6368.mk index e3aa40d404c..83cd096959b 100644 --- a/target/linux/bmips/image/bcm6368.mk +++ b/target/linux/bmips/image/bcm6368.mk @@ -14,6 +14,79 @@ define Device/comtrend_vr-3025u endef TARGET_DEVICES += comtrend_vr-3025u +define Device/comtrend_vr-3025un + $(Device/bcm63xx-cfe) + DEVICE_VENDOR := Comtrend + DEVICE_MODEL := VR-3025un + CHIP_ID := 6368 + CFE_BOARD_ID := 96368M-1341N + FLASH_MB := 8 + DEVICE_PACKAGES += $(USB2_PACKAGES) \ + $(B43_PACKAGES) broadcom-43222-sprom \ + kmod-leds-gpio +endef +TARGET_DEVICES += comtrend_vr-3025un + +define Device/comtrend_wap-5813n + $(Device/bcm63xx-cfe) + DEVICE_VENDOR := Comtrend + DEVICE_MODEL := WAP-5813n + CHIP_ID := 6368 + SOC := bcm6369 + CFE_BOARD_ID := 96369R-1231N + FLASH_MB := 8 + DEVICE_PACKAGES += $(USB2_PACKAGES) \ + $(B43_PACKAGES) broadcom-4322-sprom \ + kmod-leds-gpio +endef +TARGET_DEVICES += comtrend_wap-5813n + +define Device/netgear_dgnd3700-v1 + $(Device/bcm63xx-netgear) + DEVICE_VENDOR := NETGEAR + DEVICE_MODEL := DGND3700 + DEVICE_VARIANT := v1 + CFE_BOARD_ID := 96368MVWG + CHIP_ID := 6368 + BLOCKSIZE := 0x20000 + NETGEAR_BOARD_ID := U12L144T01_NETGEAR_NEWLED + NETGEAR_REGION := 1 + DEVICE_PACKAGES += $(USB2_PACKAGES) \ + $(B43_PACKAGES) \ + kmod-leds-gpio +endef +TARGET_DEVICES += netgear_dgnd3700-v1 + +define Device/netgear_dgnd3800b + $(Device/bcm63xx-netgear) + DEVICE_VENDOR := NETGEAR + DEVICE_MODEL := DGND3800B + CFE_BOARD_ID := 96368MVWG + CHIP_ID := 6368 + BLOCKSIZE := 0x20000 + NETGEAR_BOARD_ID := U12L144T11_NETGEAR_NEWLED + NETGEAR_REGION := 1 + DEVICE_PACKAGES += $(USB2_PACKAGES) \ + $(B43_PACKAGES) \ + kmod-leds-gpio +endef +TARGET_DEVICES += netgear_dgnd3800b + +define Device/netgear_evg2000 + $(Device/bcm63xx-netgear) + DEVICE_MODEL := EVG2000 + CFE_BOARD_ID := 96369PVG + CHIP_ID := 6368 + SOC := bcm6369 + BLOCKSIZE := 0x20000 + NETGEAR_BOARD_ID := U12H154T90_NETGEAR + NETGEAR_REGION := 1 + DEVICE_PACKAGES += $(USB2_PACKAGES) \ + $(B43_PACKAGES) broadcom-4322-sprom \ + kmod-leds-gpio +endef +TARGET_DEVICES += netgear_evg2000 + define Device/observa_vh4032n $(Device/bcm63xx-cfe) DEVICE_VENDOR := Observa diff --git a/target/linux/generic/backport-5.15/202-v6.1-kallsyms-support-big-kernel-symbols.patch b/target/linux/generic/backport-5.15/202-v6.1-kallsyms-support-big-kernel-symbols.patch new file mode 100644 index 00000000000..786a2d93b50 --- /dev/null +++ b/target/linux/generic/backport-5.15/202-v6.1-kallsyms-support-big-kernel-symbols.patch @@ -0,0 +1,128 @@ +From 73bbb94466fd3f8b313eeb0b0467314a262dddb3 Mon Sep 17 00:00:00 2001 +From: Miguel Ojeda +Date: Mon, 5 Apr 2021 04:58:39 +0200 +Subject: [PATCH] kallsyms: support "big" kernel symbols + +Rust symbols can become quite long due to namespacing introduced +by modules, types, traits, generics, etc. + +Increasing to 255 is not enough in some cases, therefore +introduce longer lengths to the symbol table. + +In order to avoid increasing all lengths to 2 bytes (since most +of them are small, including many Rust ones), use ULEB128 to +keep smaller symbols in 1 byte, with the rest in 2 bytes. + +Reviewed-by: Kees Cook +Reviewed-by: Greg Kroah-Hartman +Co-developed-by: Alex Gaynor +Signed-off-by: Alex Gaynor +Co-developed-by: Wedson Almeida Filho +Signed-off-by: Wedson Almeida Filho +Co-developed-by: Gary Guo +Signed-off-by: Gary Guo +Co-developed-by: Boqun Feng +Signed-off-by: Boqun Feng +Co-developed-by: Matthew Wilcox +Signed-off-by: Matthew Wilcox +Signed-off-by: Miguel Ojeda +--- + kernel/kallsyms.c | 26 ++++++++++++++++++++++---- + scripts/kallsyms.c | 29 ++++++++++++++++++++++++++--- + 2 files changed, 48 insertions(+), 7 deletions(-) + +--- a/kernel/kallsyms.c ++++ b/kernel/kallsyms.c +@@ -69,12 +69,20 @@ static unsigned int kallsyms_expand_symb + data = &kallsyms_names[off]; + len = *data; + data++; ++ off++; ++ ++ /* If MSB is 1, it is a "big" symbol, so needs an additional byte. */ ++ if ((len & 0x80) != 0) { ++ len = (len & 0x7F) | (*data << 7); ++ data++; ++ off++; ++ } + + /* + * Update the offset to return the offset for the next symbol on + * the compressed stream. + */ +- off += len + 1; ++ off += len; + + /* + * For every byte on the compressed symbol data, copy the table +@@ -127,7 +135,7 @@ static char kallsyms_get_symbol_type(uns + static unsigned int get_symbol_offset(unsigned long pos) + { + const u8 *name; +- int i; ++ int i, len; + + /* + * Use the closest marker we have. We have markers every 256 positions, +@@ -141,8 +149,18 @@ static unsigned int get_symbol_offset(un + * so we just need to add the len to the current pointer for every + * symbol we wish to skip. + */ +- for (i = 0; i < (pos & 0xFF); i++) +- name = name + (*name) + 1; ++ for (i = 0; i < (pos & 0xFF); i++) { ++ len = *name; ++ ++ /* ++ * If MSB is 1, it is a "big" symbol, so we need to look into ++ * the next byte (and skip it, too). ++ */ ++ if ((len & 0x80) != 0) ++ len = ((len & 0x7F) | (name[1] << 7)) + 1; ++ ++ name = name + len + 1; ++ } + + return name - kallsyms_names; + } +--- a/scripts/kallsyms.c ++++ b/scripts/kallsyms.c +@@ -470,12 +470,35 @@ static void write_src(void) + if ((i & 0xFF) == 0) + markers[i >> 8] = off; + +- printf("\t.byte 0x%02x", table[i]->len); ++ /* There cannot be any symbol of length zero. */ ++ if (table[i]->len == 0) { ++ fprintf(stderr, "kallsyms failure: " ++ "unexpected zero symbol length\n"); ++ exit(EXIT_FAILURE); ++ } ++ ++ /* Only lengths that fit in up-to-two-byte ULEB128 are supported. */ ++ if (table[i]->len > 0x3FFF) { ++ fprintf(stderr, "kallsyms failure: " ++ "unexpected huge symbol length\n"); ++ exit(EXIT_FAILURE); ++ } ++ ++ /* Encode length with ULEB128. */ ++ if (table[i]->len <= 0x7F) { ++ /* Most symbols use a single byte for the length. */ ++ printf("\t.byte 0x%02x", table[i]->len); ++ off += table[i]->len + 1; ++ } else { ++ /* "Big" symbols use two bytes. */ ++ printf("\t.byte 0x%02x, 0x%02x", ++ (table[i]->len & 0x7F) | 0x80, ++ (table[i]->len >> 7) & 0x7F); ++ off += table[i]->len + 2; ++ } + for (k = 0; k < table[i]->len; k++) + printf(", 0x%02x", table[i]->sym[k]); + printf("\n"); +- +- off += table[i]->len + 1; + } + printf("\n"); + diff --git a/target/linux/generic/backport-5.15/303-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch b/target/linux/generic/backport-5.15/303-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch new file mode 100644 index 00000000000..7c1507bba7e --- /dev/null +++ b/target/linux/generic/backport-5.15/303-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch @@ -0,0 +1,63 @@ +From 579aee9fc594af94c242068c011b0233563d4bbf Mon Sep 17 00:00:00 2001 +From: Stephen Rothwell +Date: Mon, 10 Oct 2022 16:57:21 +1100 +Subject: [PATCH] powerpc: suppress some linker warnings in recent linker + versions + +This is a follow on from commit + + 0d362be5b142 ("Makefile: link with -z noexecstack --no-warn-rwx-segments") + +for arch/powerpc/boot to address wanrings like: + + ld: warning: opal-calls.o: missing .note.GNU-stack section implies executable stack + ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker + ld: warning: arch/powerpc/boot/zImage.epapr has a LOAD segment with RWX permissions + +This fixes issue https://github.com/linuxppc/issues/issues/417 + +Signed-off-by: Stephen Rothwell +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20221010165721.106267e6@canb.auug.org.au +--- + arch/powerpc/boot/wrapper | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/boot/wrapper ++++ b/arch/powerpc/boot/wrapper +@@ -213,6 +213,11 @@ ld_version() + }' + } + ++ld_is_lld() ++{ ++ ${CROSS}ld -V 2>&1 | grep -q LLD ++} ++ + # Do not include PT_INTERP segment when linking pie. Non-pie linking + # just ignores this option. + LD_VERSION=$(${CROSS}ld --version | ld_version) +@@ -221,6 +226,14 @@ if [ "$LD_VERSION" -ge "$LD_NO_DL_MIN_VE + nodl="--no-dynamic-linker" + fi + ++# suppress some warnings in recent ld versions ++nowarn="-z noexecstack" ++if ! ld_is_lld; then ++ if [ "$LD_VERSION" -ge "$(echo 2.39 | ld_version)" ]; then ++ nowarn="$nowarn --no-warn-rwx-segments" ++ fi ++fi ++ + platformo=$object/"$platform".o + lds=$object/zImage.lds + ext=strip +@@ -502,7 +515,7 @@ if [ "$platform" != "miboot" ]; then + text_start="-Ttext $link_address" + fi + #link everything +- ${CROSS}ld -m $format -T $lds $text_start $pie $nodl $rodynamic $notext -o "$ofile" $map \ ++ ${CROSS}ld -m $format -T $lds $text_start $pie $nodl $nowarn $rodynamic $notext -o "$ofile" $map \ + $platformo $tmp $object/wrapper.a + rm $tmp + fi diff --git a/target/linux/generic/backport-5.15/350-v5.18-regmap-add-configurable-downshift-for-addresses.patch b/target/linux/generic/backport-5.15/350-v5.18-regmap-add-configurable-downshift-for-addresses.patch index 99cd89ea002..690e85d34be 100644 --- a/target/linux/generic/backport-5.15/350-v5.18-regmap-add-configurable-downshift-for-addresses.patch +++ b/target/linux/generic/backport-5.15/350-v5.18-regmap-add-configurable-downshift-for-addresses.patch @@ -53,7 +53,7 @@ Signed-off-by: Mark Brown map->format.format_write(map, reg, val); trace_regmap_hw_write_start(map, reg, 1); -@@ -2346,6 +2349,7 @@ static int _regmap_raw_multi_reg_write(s +@@ -2348,6 +2351,7 @@ static int _regmap_raw_multi_reg_write(s unsigned int reg = regs[i].reg; unsigned int val = regs[i].def; trace_regmap_hw_write_start(map, reg, 1); @@ -61,7 +61,7 @@ Signed-off-by: Mark Brown map->format.format_reg(u8, reg, map->reg_shift); u8 += reg_bytes + pad_bytes; map->format.format_val(u8, val, 0); -@@ -2673,6 +2677,7 @@ static int _regmap_raw_read(struct regma +@@ -2675,6 +2679,7 @@ static int _regmap_raw_read(struct regma return ret; } diff --git a/target/linux/generic/backport-5.15/351-v5.18-regmap-allow-a-defined-reg_base-to-be-added-to-every.patch b/target/linux/generic/backport-5.15/351-v5.18-regmap-allow-a-defined-reg_base-to-be-added-to-every.patch index 0f32288fcab..ffde9e5d0c5 100644 --- a/target/linux/generic/backport-5.15/351-v5.18-regmap-allow-a-defined-reg_base-to-be-added-to-every.patch +++ b/target/linux/generic/backport-5.15/351-v5.18-regmap-allow-a-defined-reg_base-to-be-added-to-every.patch @@ -58,7 +58,7 @@ Signed-off-by: Mark Brown reg >>= map->format.reg_downshift; map->format.format_write(map, reg, val); -@@ -2349,6 +2353,7 @@ static int _regmap_raw_multi_reg_write(s +@@ -2351,6 +2355,7 @@ static int _regmap_raw_multi_reg_write(s unsigned int reg = regs[i].reg; unsigned int val = regs[i].def; trace_regmap_hw_write_start(map, reg, 1); @@ -66,7 +66,7 @@ Signed-off-by: Mark Brown reg >>= map->format.reg_downshift; map->format.format_reg(u8, reg, map->reg_shift); u8 += reg_bytes + pad_bytes; -@@ -2677,6 +2682,7 @@ static int _regmap_raw_read(struct regma +@@ -2679,6 +2684,7 @@ static int _regmap_raw_read(struct regma return ret; } diff --git a/target/linux/generic/backport-5.15/352-v6.3-regmap-apply-reg_base-and-reg_downshift-for-single-r.patch b/target/linux/generic/backport-5.15/352-v6.3-regmap-apply-reg_base-and-reg_downshift-for-single-r.patch index 804f68d23c5..34b587f5582 100644 --- a/target/linux/generic/backport-5.15/352-v6.3-regmap-apply-reg_base-and-reg_downshift-for-single-r.patch +++ b/target/linux/generic/backport-5.15/352-v6.3-regmap-apply-reg_base-and-reg_downshift-for-single-r.patch @@ -37,7 +37,7 @@ Signed-off-by: Mark Brown return map->bus->reg_write(map->bus_context, reg, val); } -@@ -2703,6 +2705,8 @@ static int _regmap_bus_reg_read(void *co +@@ -2705,6 +2707,8 @@ static int _regmap_bus_reg_read(void *co { struct regmap *map = context; @@ -46,7 +46,7 @@ Signed-off-by: Mark Brown return map->bus->reg_read(map->bus_context, reg, val); } -@@ -3078,6 +3082,8 @@ static int _regmap_update_bits(struct re +@@ -3080,6 +3084,8 @@ static int _regmap_update_bits(struct re *change = false; if (regmap_volatile(map, reg) && map->reg_update_bits) { diff --git a/target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch b/target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch index 9e383de92cd..f4c5b9afee4 100644 --- a/target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch +++ b/target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch @@ -87,9 +87,9 @@ Signed-off-by: David S. Miller help --- a/net/core/page_pool.c +++ b/net/core/page_pool.c -@@ -26,6 +26,13 @@ - - #define BIAS_MAX LONG_MAX +@@ -49,6 +49,13 @@ static void page_pool_producer_unlock(st + spin_unlock_bh(&pool->ring.producer_lock); + } +#ifdef CONFIG_PAGE_POOL_STATS +/* alloc_stat_inc is intended to be used in softirq context */ @@ -101,7 +101,7 @@ Signed-off-by: David S. Miller static int page_pool_init(struct page_pool *pool, const struct page_pool_params *params) { -@@ -117,8 +124,10 @@ static struct page *page_pool_refill_all +@@ -140,8 +147,10 @@ static struct page *page_pool_refill_all int pref_nid; /* preferred NUMA node */ /* Quicker fallback, avoid locks when ring is empty */ @@ -113,7 +113,7 @@ Signed-off-by: David S. Miller /* Softirq guarantee CPU and thus NUMA node is stable. This, * assumes CPU refilling driver RX-ring will also run RX-NAPI. -@@ -148,14 +157,17 @@ static struct page *page_pool_refill_all +@@ -171,14 +180,17 @@ static struct page *page_pool_refill_all * This limit stress on page buddy alloactor. */ page_pool_return_page(pool, page); @@ -132,7 +132,7 @@ Signed-off-by: David S. Miller spin_unlock(&r->consumer_lock); return page; -@@ -170,6 +182,7 @@ static struct page *__page_pool_get_cach +@@ -193,6 +205,7 @@ static struct page *__page_pool_get_cach if (likely(pool->alloc.count)) { /* Fast-path */ page = pool->alloc.cache[--pool->alloc.count]; @@ -140,7 +140,7 @@ Signed-off-by: David S. Miller } else { page = page_pool_refill_alloc_cache(pool); } -@@ -241,6 +254,7 @@ static struct page *__page_pool_alloc_pa +@@ -264,6 +277,7 @@ static struct page *__page_pool_alloc_pa return NULL; } @@ -148,7 +148,7 @@ Signed-off-by: David S. Miller page_pool_set_pp_info(pool, page); /* Track how many pages are held 'in-flight' */ -@@ -295,10 +309,12 @@ static struct page *__page_pool_alloc_pa +@@ -318,10 +332,12 @@ static struct page *__page_pool_alloc_pa } /* Return last page */ diff --git a/target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch b/target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch index fb11f0035f8..b425b78c753 100644 --- a/target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch +++ b/target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch @@ -53,7 +53,7 @@ Signed-off-by: David S. Miller /* A page_pool is strictly tied to a single RX-queue being --- a/net/core/page_pool.c +++ b/net/core/page_pool.c -@@ -29,8 +29,15 @@ +@@ -52,8 +52,15 @@ static void page_pool_producer_unlock(st #ifdef CONFIG_PAGE_POOL_STATS /* alloc_stat_inc is intended to be used in softirq context */ #define alloc_stat_inc(pool, __stat) (pool->alloc_stats.__stat++) @@ -69,7 +69,7 @@ Signed-off-by: David S. Miller #endif static int page_pool_init(struct page_pool *pool, -@@ -80,6 +87,12 @@ static int page_pool_init(struct page_po +@@ -103,6 +110,12 @@ static int page_pool_init(struct page_po pool->p.flags & PP_FLAG_PAGE_FRAG) return -EINVAL; @@ -82,7 +82,7 @@ Signed-off-by: David S. Miller if (ptr_ring_init(&pool->ring, ring_qsize, GFP_KERNEL) < 0) return -ENOMEM; -@@ -412,7 +425,12 @@ static bool page_pool_recycle_in_ring(st +@@ -435,7 +448,12 @@ static bool page_pool_recycle_in_ring(st else ret = ptr_ring_produce_bh(&pool->ring, page); @@ -96,7 +96,7 @@ Signed-off-by: David S. Miller } /* Only allow direct recycling in special circumstances, into the -@@ -423,11 +441,14 @@ static bool page_pool_recycle_in_ring(st +@@ -446,11 +464,14 @@ static bool page_pool_recycle_in_ring(st static bool page_pool_recycle_in_cache(struct page *page, struct page_pool *pool) { @@ -112,7 +112,7 @@ Signed-off-by: David S. Miller return true; } -@@ -482,6 +503,7 @@ __page_pool_put_page(struct page_pool *p +@@ -505,6 +526,7 @@ __page_pool_put_page(struct page_pool *p * doing refcnt based recycle tricks, meaning another process * will be invoking put_page. */ @@ -120,7 +120,7 @@ Signed-off-by: David S. Miller /* Do not replace this with page_pool_return_page() */ page_pool_release_page(pool, page); put_page(page); -@@ -495,6 +517,7 @@ void page_pool_put_page(struct page_pool +@@ -518,6 +540,7 @@ void page_pool_put_page(struct page_pool page = __page_pool_put_page(pool, page, dma_sync_size, allow_direct); if (page && !page_pool_recycle_in_ring(pool, page)) { /* Cache full, fallback to free pages */ @@ -128,7 +128,7 @@ Signed-off-by: David S. Miller page_pool_return_page(pool, page); } } -@@ -641,6 +664,9 @@ static void page_pool_free(struct page_p +@@ -665,6 +688,9 @@ static void page_pool_free(struct page_p if (pool->p.flags & PP_FLAG_DMA_MAP) put_device(pool->p.dev); diff --git a/target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch b/target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch index 41188fb7f27..e1a7635133c 100644 --- a/target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch +++ b/target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch @@ -43,7 +43,7 @@ Signed-off-by: David S. Miller struct page_pool { --- a/net/core/page_pool.c +++ b/net/core/page_pool.c -@@ -35,6 +35,31 @@ +@@ -58,6 +58,31 @@ static void page_pool_producer_unlock(st struct page_pool_recycle_stats __percpu *s = pool->recycle_stats; \ this_cpu_inc(s->__stat); \ } while (0) diff --git a/target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch b/target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch index 6ae3fb71331..f438ef3a599 100644 --- a/target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch +++ b/target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch @@ -16,7 +16,7 @@ Signed-off-by: Paolo Abeni --- a/net/core/page_pool.c +++ b/net/core/page_pool.c -@@ -36,6 +36,12 @@ +@@ -59,6 +59,12 @@ static void page_pool_producer_unlock(st this_cpu_inc(s->__stat); \ } while (0) @@ -29,7 +29,7 @@ Signed-off-by: Paolo Abeni bool page_pool_get_stats(struct page_pool *pool, struct page_pool_stats *stats) { -@@ -63,6 +69,7 @@ EXPORT_SYMBOL(page_pool_get_stats); +@@ -86,6 +92,7 @@ EXPORT_SYMBOL(page_pool_get_stats); #else #define alloc_stat_inc(pool, __stat) #define recycle_stat_inc(pool, __stat) @@ -37,9 +37,9 @@ Signed-off-by: Paolo Abeni #endif static int page_pool_init(struct page_pool *pool, -@@ -569,9 +576,13 @@ void page_pool_put_page_bulk(struct page +@@ -593,9 +600,13 @@ void page_pool_put_page_bulk(struct page /* Bulk producer into ptr_ring page_pool cache */ - page_pool_ring_lock(pool); + in_softirq = page_pool_producer_lock(pool); for (i = 0; i < bulk_len; i++) { - if (__ptr_ring_produce(&pool->ring, data[i])) - break; /* ring full */ @@ -50,6 +50,6 @@ Signed-off-by: Paolo Abeni + } } + recycle_stat_add(pool, ring, i); - page_pool_ring_unlock(pool); + page_pool_producer_unlock(pool, in_softirq); /* Hopefully all pages was return into ptr_ring */ diff --git a/target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch b/target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch index e5cf91ceeed..3ff136b0842 100644 --- a/target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch +++ b/target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch @@ -62,7 +62,7 @@ Signed-off-by: David S. Miller #include -@@ -42,6 +43,20 @@ +@@ -65,6 +66,20 @@ static void page_pool_producer_unlock(st this_cpu_add(s->__stat, val); \ } while (0) @@ -83,7 +83,7 @@ Signed-off-by: David S. Miller bool page_pool_get_stats(struct page_pool *pool, struct page_pool_stats *stats) { -@@ -50,7 +65,13 @@ bool page_pool_get_stats(struct page_poo +@@ -73,7 +88,13 @@ bool page_pool_get_stats(struct page_poo if (!stats) return false; @@ -98,7 +98,7 @@ Signed-off-by: David S. Miller for_each_possible_cpu(cpu) { const struct page_pool_recycle_stats *pcpu = -@@ -66,6 +87,46 @@ bool page_pool_get_stats(struct page_poo +@@ -89,6 +110,46 @@ bool page_pool_get_stats(struct page_poo return true; } EXPORT_SYMBOL(page_pool_get_stats); diff --git a/target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch b/target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch index 86d24367dd6..e126b21417f 100644 --- a/target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch +++ b/target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch @@ -48,7 +48,7 @@ Signed-off-by: Alexei Starovoitov int xdp_rxq_info_reg(struct xdp_rxq_info *xdp_rxq, --- a/net/core/xdp.c +++ b/net/core/xdp.c -@@ -376,12 +376,38 @@ static void __xdp_return(void *data, str +@@ -409,12 +409,38 @@ static void __xdp_return(void *data, str void xdp_return_frame(struct xdp_frame *xdpf) { @@ -87,7 +87,7 @@ Signed-off-by: Alexei Starovoitov __xdp_return(xdpf->data, &xdpf->mem, true, NULL); } EXPORT_SYMBOL_GPL(xdp_return_frame_rx_napi); -@@ -417,7 +443,7 @@ void xdp_return_frame_bulk(struct xdp_fr +@@ -450,7 +476,7 @@ void xdp_return_frame_bulk(struct xdp_fr struct xdp_mem_allocator *xa; if (mem->type != MEM_TYPE_PAGE_POOL) { @@ -96,7 +96,7 @@ Signed-off-by: Alexei Starovoitov return; } -@@ -436,12 +462,38 @@ void xdp_return_frame_bulk(struct xdp_fr +@@ -469,12 +495,38 @@ void xdp_return_frame_bulk(struct xdp_fr bq->xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params); } diff --git a/target/linux/generic/backport-5.15/610-v6.3-net-page_pool-use-in_softirq-instead.patch b/target/linux/generic/backport-5.15/610-v6.3-net-page_pool-use-in_softirq-instead.patch deleted file mode 100644 index 71e11405958..00000000000 --- a/target/linux/generic/backport-5.15/610-v6.3-net-page_pool-use-in_softirq-instead.patch +++ /dev/null @@ -1,56 +0,0 @@ -From: Qingfang DENG -Date: Fri, 3 Feb 2023 09:16:11 +0800 -Subject: [PATCH] net: page_pool: use in_softirq() instead - -We use BH context only for synchronization, so we don't care if it's -actually serving softirq or not. - -As a side node, in case of threaded NAPI, in_serving_softirq() will -return false because it's in process context with BH off, making -page_pool_recycle_in_cache() unreachable. - -Signed-off-by: Qingfang DENG ---- - ---- a/include/net/page_pool.h -+++ b/include/net/page_pool.h -@@ -357,7 +357,7 @@ static inline void page_pool_nid_changed - static inline void page_pool_ring_lock(struct page_pool *pool) - __acquires(&pool->ring.producer_lock) - { -- if (in_serving_softirq()) -+ if (in_softirq()) - spin_lock(&pool->ring.producer_lock); - else - spin_lock_bh(&pool->ring.producer_lock); -@@ -366,7 +366,7 @@ static inline void page_pool_ring_lock(s - static inline void page_pool_ring_unlock(struct page_pool *pool) - __releases(&pool->ring.producer_lock) - { -- if (in_serving_softirq()) -+ if (in_softirq()) - spin_unlock(&pool->ring.producer_lock); - else - spin_unlock_bh(&pool->ring.producer_lock); ---- a/net/core/page_pool.c -+++ b/net/core/page_pool.c -@@ -512,8 +512,8 @@ static void page_pool_return_page(struct - static bool page_pool_recycle_in_ring(struct page_pool *pool, struct page *page) - { - int ret; -- /* BH protection not needed if current is serving softirq */ -- if (in_serving_softirq()) -+ /* BH protection not needed if current is softirq */ -+ if (in_softirq()) - ret = ptr_ring_produce(&pool->ring, page); - else - ret = ptr_ring_produce_bh(&pool->ring, page); -@@ -576,7 +576,7 @@ __page_pool_put_page(struct page_pool *p - page_pool_dma_sync_for_device(pool, page, - dma_sync_size); - -- if (allow_direct && in_serving_softirq() && -+ if (allow_direct && in_softirq() && - page_pool_recycle_in_cache(page, pool)) - return NULL; - diff --git a/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch b/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch index f2b651f0c61..f56a9685895 100644 --- a/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch +++ b/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch @@ -94,7 +94,7 @@ Signed-off-by: David S. Miller /* * Configuration data for this switch. */ -@@ -584,6 +589,13 @@ struct dsa_switch_ops { +@@ -612,6 +617,13 @@ struct dsa_switch_ops { enum dsa_tag_protocol mprot); int (*change_tag_protocol)(struct dsa_switch *ds, int port, enum dsa_tag_protocol proto); diff --git a/target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch b/target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch index b10e6da0e9a..b4387865363 100644 --- a/target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch +++ b/target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch @@ -26,7 +26,7 @@ Signed-off-by: David S. Miller --- a/include/net/dsa.h +++ b/include/net/dsa.h -@@ -626,6 +626,8 @@ struct dsa_switch_ops { +@@ -654,6 +654,8 @@ struct dsa_switch_ops { /* * PHYLINK integration */ diff --git a/target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch b/target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch index d70b9aa6a47..1d9616c0db7 100644 --- a/target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch +++ b/target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch @@ -24,7 +24,7 @@ Signed-off-by: Jakub Kicinski --- a/include/net/dsa.h +++ b/include/net/dsa.h -@@ -626,8 +626,8 @@ struct dsa_switch_ops { +@@ -654,8 +654,8 @@ struct dsa_switch_ops { /* * PHYLINK integration */ diff --git a/target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch b/target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch index 2af5cb9d9db..9791ad2ac91 100644 --- a/target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch +++ b/target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch @@ -16,7 +16,7 @@ Signed-off-by: David S. Miller --- a/include/net/dsa.h +++ b/include/net/dsa.h -@@ -631,6 +631,9 @@ struct dsa_switch_ops { +@@ -659,6 +659,9 @@ struct dsa_switch_ops { void (*phylink_validate)(struct dsa_switch *ds, int port, unsigned long *supported, struct phylink_link_state *state); diff --git a/target/linux/generic/backport-5.15/703-10-v5.16-net-dsa-introduce-helpers-for-iterating-through-port.patch b/target/linux/generic/backport-5.15/703-10-v5.16-net-dsa-introduce-helpers-for-iterating-through-port.patch deleted file mode 100644 index a55623519ce..00000000000 --- a/target/linux/generic/backport-5.15/703-10-v5.16-net-dsa-introduce-helpers-for-iterating-through-port.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 82b318983c515f29b8b3a0dad9f6a5fe8a68a7f4 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Wed, 20 Oct 2021 20:49:49 +0300 -Subject: [PATCH] net: dsa: introduce helpers for iterating through ports using - dp - -Since the DSA conversion from the ds->ports array into the dst->ports -list, the DSA API has encouraged driver writers, as well as the core -itself, to write inefficient code. - -Currently, code that wants to filter by a specific type of port when -iterating, like {!unused, user, cpu, dsa}, uses the dsa_is_*_port helper. -Under the hood, this uses dsa_to_port which iterates again through -dst->ports. But the driver iterates through the port list already, so -the complexity is quadratic for the typical case of a single-switch -tree. - -This patch introduces some iteration helpers where the iterator is -already a struct dsa_port *dp, so that the other variant of the -filtering functions, dsa_port_is_{unused,user,cpu_dsa}, can be used -directly on the iterator. This eliminates the second lookup. - -These functions can be used both by the core and by drivers. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - include/net/dsa.h | 28 ++++++++++++++++++++++++++++ - 1 file changed, 28 insertions(+) - ---- a/include/net/dsa.h -+++ b/include/net/dsa.h -@@ -476,6 +476,34 @@ static inline bool dsa_is_user_port(stru - return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_USER; - } - -+#define dsa_tree_for_each_user_port(_dp, _dst) \ -+ list_for_each_entry((_dp), &(_dst)->ports, list) \ -+ if (dsa_port_is_user((_dp))) -+ -+#define dsa_switch_for_each_port(_dp, _ds) \ -+ list_for_each_entry((_dp), &(_ds)->dst->ports, list) \ -+ if ((_dp)->ds == (_ds)) -+ -+#define dsa_switch_for_each_port_safe(_dp, _next, _ds) \ -+ list_for_each_entry_safe((_dp), (_next), &(_ds)->dst->ports, list) \ -+ if ((_dp)->ds == (_ds)) -+ -+#define dsa_switch_for_each_port_continue_reverse(_dp, _ds) \ -+ list_for_each_entry_continue_reverse((_dp), &(_ds)->dst->ports, list) \ -+ if ((_dp)->ds == (_ds)) -+ -+#define dsa_switch_for_each_available_port(_dp, _ds) \ -+ dsa_switch_for_each_port((_dp), (_ds)) \ -+ if (!dsa_port_is_unused((_dp))) -+ -+#define dsa_switch_for_each_user_port(_dp, _ds) \ -+ dsa_switch_for_each_port((_dp), (_ds)) \ -+ if (dsa_port_is_user((_dp))) -+ -+#define dsa_switch_for_each_cpu_port(_dp, _ds) \ -+ dsa_switch_for_each_port((_dp), (_ds)) \ -+ if (dsa_port_is_cpu((_dp))) -+ - static inline u32 dsa_user_ports(struct dsa_switch *ds) - { - u32 mask = 0; diff --git a/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch b/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch index 435f282845f..f2ead18c36e 100644 --- a/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch +++ b/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch @@ -23,7 +23,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2412,6 +2412,32 @@ mt7531_setup(struct dsa_switch *ds) +@@ -2444,6 +2444,32 @@ mt7531_setup(struct dsa_switch *ds) return 0; } @@ -56,7 +56,7 @@ Signed-off-by: Paolo Abeni static bool mt7530_phy_mode_supported(struct dsa_switch *ds, int port, const struct phylink_link_state *state) -@@ -2448,6 +2474,37 @@ static bool mt7531_is_rgmii_port(struct +@@ -2480,6 +2506,37 @@ static bool mt7531_is_rgmii_port(struct return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII); } @@ -94,7 +94,7 @@ Signed-off-by: Paolo Abeni static bool mt7531_phy_mode_supported(struct dsa_switch *ds, int port, const struct phylink_link_state *state) -@@ -2924,6 +2981,18 @@ mt7531_cpu_port_config(struct dsa_switch +@@ -2956,6 +3013,18 @@ mt7531_cpu_port_config(struct dsa_switch return 0; } @@ -113,7 +113,7 @@ Signed-off-by: Paolo Abeni static void mt7530_mac_port_validate(struct dsa_switch *ds, int port, unsigned long *supported) -@@ -3159,6 +3228,7 @@ static const struct dsa_switch_ops mt753 +@@ -3191,6 +3260,7 @@ static const struct dsa_switch_ops mt753 .port_vlan_del = mt7530_port_vlan_del, .port_mirror_add = mt753x_port_mirror_add, .port_mirror_del = mt753x_port_mirror_del, @@ -121,7 +121,7 @@ Signed-off-by: Paolo Abeni .phylink_validate = mt753x_phylink_validate, .phylink_mac_link_state = mt753x_phylink_mac_link_state, .phylink_mac_config = mt753x_phylink_mac_config, -@@ -3176,6 +3246,7 @@ static const struct mt753x_info mt753x_t +@@ -3208,6 +3278,7 @@ static const struct mt753x_info mt753x_t .phy_read = mt7530_phy_read, .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, @@ -129,7 +129,7 @@ Signed-off-by: Paolo Abeni .phy_mode_supported = mt7530_phy_mode_supported, .mac_port_validate = mt7530_mac_port_validate, .mac_port_get_state = mt7530_phylink_mac_link_state, -@@ -3187,6 +3258,7 @@ static const struct mt753x_info mt753x_t +@@ -3219,6 +3290,7 @@ static const struct mt753x_info mt753x_t .phy_read = mt7530_phy_read, .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, @@ -137,7 +137,7 @@ Signed-off-by: Paolo Abeni .phy_mode_supported = mt7530_phy_mode_supported, .mac_port_validate = mt7530_mac_port_validate, .mac_port_get_state = mt7530_phylink_mac_link_state, -@@ -3199,6 +3271,7 @@ static const struct mt753x_info mt753x_t +@@ -3231,6 +3303,7 @@ static const struct mt753x_info mt753x_t .phy_write = mt7531_ind_phy_write, .pad_setup = mt7531_pad_setup, .cpu_port_config = mt7531_cpu_port_config, @@ -145,7 +145,7 @@ Signed-off-by: Paolo Abeni .phy_mode_supported = mt7531_phy_mode_supported, .mac_port_validate = mt7531_mac_port_validate, .mac_port_get_state = mt7531_phylink_mac_link_state, -@@ -3261,6 +3334,7 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3293,6 +3366,7 @@ mt7530_probe(struct mdio_device *mdiodev */ if (!priv->info->sw_setup || !priv->info->pad_setup || !priv->info->phy_read || !priv->info->phy_write || diff --git a/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch b/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch index 38a24dc46b0..228016383d9 100644 --- a/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch +++ b/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch @@ -21,7 +21,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2438,37 +2438,6 @@ static void mt7530_mac_port_get_caps(str +@@ -2470,37 +2470,6 @@ static void mt7530_mac_port_get_caps(str } } @@ -59,7 +59,7 @@ Signed-off-by: Paolo Abeni static bool mt7531_is_rgmii_port(struct mt7530_priv *priv, u32 port) { return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII); -@@ -2505,44 +2474,6 @@ static void mt7531_mac_port_get_caps(str +@@ -2537,44 +2506,6 @@ static void mt7531_mac_port_get_caps(str } } @@ -104,7 +104,7 @@ Signed-off-by: Paolo Abeni static int mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state) { -@@ -2797,9 +2728,6 @@ mt753x_phylink_mac_config(struct dsa_swi +@@ -2829,9 +2760,6 @@ mt753x_phylink_mac_config(struct dsa_swi struct mt7530_priv *priv = ds->priv; u32 mcr_cur, mcr_new; @@ -114,7 +114,7 @@ Signed-off-by: Paolo Abeni switch (port) { case 0 ... 4: /* Internal phy */ if (state->interface != PHY_INTERFACE_MODE_GMII) -@@ -3015,12 +2943,6 @@ mt753x_phylink_validate(struct dsa_switc +@@ -3047,12 +2975,6 @@ mt753x_phylink_validate(struct dsa_switc __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; struct mt7530_priv *priv = ds->priv; @@ -127,7 +127,7 @@ Signed-off-by: Paolo Abeni phylink_set_port_modes(mask); if (state->interface != PHY_INTERFACE_MODE_TRGMII && -@@ -3247,7 +3169,6 @@ static const struct mt753x_info mt753x_t +@@ -3279,7 +3201,6 @@ static const struct mt753x_info mt753x_t .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, .mac_port_get_caps = mt7530_mac_port_get_caps, @@ -135,7 +135,7 @@ Signed-off-by: Paolo Abeni .mac_port_validate = mt7530_mac_port_validate, .mac_port_get_state = mt7530_phylink_mac_link_state, .mac_port_config = mt7530_mac_config, -@@ -3259,7 +3180,6 @@ static const struct mt753x_info mt753x_t +@@ -3291,7 +3212,6 @@ static const struct mt753x_info mt753x_t .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, .mac_port_get_caps = mt7530_mac_port_get_caps, @@ -143,7 +143,7 @@ Signed-off-by: Paolo Abeni .mac_port_validate = mt7530_mac_port_validate, .mac_port_get_state = mt7530_phylink_mac_link_state, .mac_port_config = mt7530_mac_config, -@@ -3272,7 +3192,6 @@ static const struct mt753x_info mt753x_t +@@ -3304,7 +3224,6 @@ static const struct mt753x_info mt753x_t .pad_setup = mt7531_pad_setup, .cpu_port_config = mt7531_cpu_port_config, .mac_port_get_caps = mt7531_mac_port_get_caps, @@ -151,7 +151,7 @@ Signed-off-by: Paolo Abeni .mac_port_validate = mt7531_mac_port_validate, .mac_port_get_state = mt7531_phylink_mac_link_state, .mac_port_config = mt7531_mac_config, -@@ -3335,7 +3254,6 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3367,7 +3286,6 @@ mt7530_probe(struct mdio_device *mdiodev if (!priv->info->sw_setup || !priv->info->pad_setup || !priv->info->phy_read || !priv->info->phy_write || !priv->info->mac_port_get_caps || diff --git a/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch b/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch index e607a3c7d2c..1a1802a1670 100644 --- a/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch +++ b/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch @@ -20,7 +20,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2967,11 +2967,6 @@ mt753x_phylink_validate(struct dsa_switc +@@ -2999,11 +2999,6 @@ mt753x_phylink_validate(struct dsa_switc linkmode_and(supported, supported, mask); linkmode_and(state->advertising, state->advertising, mask); diff --git a/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch b/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch index 63a33176303..636353c2d64 100644 --- a/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch +++ b/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch @@ -23,7 +23,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2545,12 +2545,13 @@ static int mt7531_rgmii_setup(struct mt7 +@@ -2577,12 +2577,13 @@ static int mt7531_rgmii_setup(struct mt7 } static void mt7531_sgmii_validate(struct mt7530_priv *priv, int port, @@ -38,7 +38,7 @@ Signed-off-by: Paolo Abeni phylink_set(supported, 2500baseX_Full); phylink_set(supported, 2500baseT_Full); } -@@ -2923,16 +2924,18 @@ static void mt753x_phylink_get_caps(stru +@@ -2955,16 +2956,18 @@ static void mt753x_phylink_get_caps(stru static void mt7530_mac_port_validate(struct dsa_switch *ds, int port, @@ -58,7 +58,7 @@ Signed-off-by: Paolo Abeni } static void -@@ -2955,12 +2958,13 @@ mt753x_phylink_validate(struct dsa_switc +@@ -2987,12 +2990,13 @@ mt753x_phylink_validate(struct dsa_switc } /* This switch only supports 1G full-duplex. */ diff --git a/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch b/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch index 97699d4c5e3..4d7569b4ce3 100644 --- a/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch +++ b/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch @@ -20,7 +20,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2544,19 +2544,6 @@ static int mt7531_rgmii_setup(struct mt7 +@@ -2576,19 +2576,6 @@ static int mt7531_rgmii_setup(struct mt7 return 0; } @@ -40,7 +40,7 @@ Signed-off-by: Paolo Abeni static void mt7531_sgmii_link_up_force(struct dsa_switch *ds, int port, unsigned int mode, phy_interface_t interface, -@@ -2923,51 +2910,21 @@ static void mt753x_phylink_get_caps(stru +@@ -2955,51 +2942,21 @@ static void mt753x_phylink_get_caps(stru } static void @@ -97,7 +97,7 @@ Signed-off-by: Paolo Abeni linkmode_and(supported, supported, mask); linkmode_and(state->advertising, state->advertising, mask); -@@ -3168,7 +3125,6 @@ static const struct mt753x_info mt753x_t +@@ -3200,7 +3157,6 @@ static const struct mt753x_info mt753x_t .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, .mac_port_get_caps = mt7530_mac_port_get_caps, @@ -105,7 +105,7 @@ Signed-off-by: Paolo Abeni .mac_port_get_state = mt7530_phylink_mac_link_state, .mac_port_config = mt7530_mac_config, }, -@@ -3179,7 +3135,6 @@ static const struct mt753x_info mt753x_t +@@ -3211,7 +3167,6 @@ static const struct mt753x_info mt753x_t .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, .mac_port_get_caps = mt7530_mac_port_get_caps, @@ -113,7 +113,7 @@ Signed-off-by: Paolo Abeni .mac_port_get_state = mt7530_phylink_mac_link_state, .mac_port_config = mt7530_mac_config, }, -@@ -3191,7 +3146,6 @@ static const struct mt753x_info mt753x_t +@@ -3223,7 +3178,6 @@ static const struct mt753x_info mt753x_t .pad_setup = mt7531_pad_setup, .cpu_port_config = mt7531_cpu_port_config, .mac_port_get_caps = mt7531_mac_port_get_caps, @@ -121,7 +121,7 @@ Signed-off-by: Paolo Abeni .mac_port_get_state = mt7531_phylink_mac_link_state, .mac_port_config = mt7531_mac_config, .mac_pcs_an_restart = mt7531_sgmii_restart_an, -@@ -3253,7 +3207,6 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3285,7 +3239,6 @@ mt7530_probe(struct mdio_device *mdiodev if (!priv->info->sw_setup || !priv->info->pad_setup || !priv->info->phy_read || !priv->info->phy_write || !priv->info->mac_port_get_caps || diff --git a/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch b/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch index b9b74833d22..fdf2a964ccf 100644 --- a/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch +++ b/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch @@ -33,7 +33,7 @@ Signed-off-by: Paolo Abeni /* String, offset, and register size in bytes if different from 4 bytes */ static const struct mt7530_mib_desc mt7530_mib[] = { MIB_DESC(1, 0x00, "TxDrop"), -@@ -2544,12 +2549,11 @@ static int mt7531_rgmii_setup(struct mt7 +@@ -2576,12 +2581,11 @@ static int mt7531_rgmii_setup(struct mt7 return 0; } @@ -50,7 +50,7 @@ Signed-off-by: Paolo Abeni unsigned int val; /* For adjusting speed and duplex of SGMII force mode. */ -@@ -2575,6 +2579,9 @@ mt7531_sgmii_link_up_force(struct dsa_sw +@@ -2607,6 +2611,9 @@ mt7531_sgmii_link_up_force(struct dsa_sw /* MT7531 SGMII 1G force mode can only work in full duplex mode, * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not. @@ -60,7 +60,7 @@ Signed-off-by: Paolo Abeni */ if ((speed == SPEED_10 || speed == SPEED_100) && duplex != DUPLEX_FULL) -@@ -2650,9 +2657,10 @@ static int mt7531_sgmii_setup_mode_an(st +@@ -2682,9 +2689,10 @@ static int mt7531_sgmii_setup_mode_an(st return 0; } @@ -73,7 +73,7 @@ Signed-off-by: Paolo Abeni u32 val; /* Only restart AN when AN is enabled */ -@@ -2709,6 +2717,24 @@ mt753x_mac_config(struct dsa_switch *ds, +@@ -2741,6 +2749,24 @@ mt753x_mac_config(struct dsa_switch *ds, return priv->info->mac_port_config(ds, port, mode, state->interface); } @@ -98,7 +98,7 @@ Signed-off-by: Paolo Abeni static void mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, const struct phylink_link_state *state) -@@ -2770,17 +2796,6 @@ unsupported: +@@ -2802,17 +2828,6 @@ unsupported: mt7530_write(priv, MT7530_PMCR_P(port), mcr_new); } @@ -116,7 +116,7 @@ Signed-off-by: Paolo Abeni static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, phy_interface_t interface) -@@ -2790,16 +2805,13 @@ static void mt753x_phylink_mac_link_down +@@ -2822,16 +2837,13 @@ static void mt753x_phylink_mac_link_down mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK); } @@ -139,7 +139,7 @@ Signed-off-by: Paolo Abeni } static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port, -@@ -2812,8 +2824,6 @@ static void mt753x_phylink_mac_link_up(s +@@ -2844,8 +2856,6 @@ static void mt753x_phylink_mac_link_up(s struct mt7530_priv *priv = ds->priv; u32 mcr; @@ -148,7 +148,7 @@ Signed-off-by: Paolo Abeni mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK; /* MT753x MAC works in 1G full duplex mode for all up-clocked -@@ -2891,6 +2901,8 @@ mt7531_cpu_port_config(struct dsa_switch +@@ -2923,6 +2933,8 @@ mt7531_cpu_port_config(struct dsa_switch return ret; mt7530_write(priv, MT7530_PMCR_P(port), PMCR_CPU_PORT_SETTING(priv->id)); @@ -157,7 +157,7 @@ Signed-off-by: Paolo Abeni mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL, speed, DUPLEX_FULL, true, true); -@@ -2930,16 +2942,13 @@ mt753x_phylink_validate(struct dsa_switc +@@ -2962,16 +2974,13 @@ mt753x_phylink_validate(struct dsa_switc linkmode_and(state->advertising, state->advertising, mask); } @@ -178,7 +178,7 @@ Signed-off-by: Paolo Abeni pmsr = mt7530_read(priv, MT7530_PMSR_P(port)); state->link = (pmsr & PMSR_LINK); -@@ -2966,8 +2975,6 @@ mt7530_phylink_mac_link_state(struct dsa +@@ -2998,8 +3007,6 @@ mt7530_phylink_mac_link_state(struct dsa state->pause |= MLO_PAUSE_RX; if (pmsr & PMSR_TX_FC) state->pause |= MLO_PAUSE_TX; @@ -187,7 +187,7 @@ Signed-off-by: Paolo Abeni } static int -@@ -3009,32 +3016,49 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 +@@ -3041,32 +3048,49 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 return 0; } @@ -249,7 +249,7 @@ Signed-off-by: Paolo Abeni if (ret) return ret; -@@ -3047,6 +3071,13 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3079,6 +3103,13 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); @@ -263,7 +263,7 @@ Signed-off-by: Paolo Abeni return ret; } -@@ -3108,9 +3139,8 @@ static const struct dsa_switch_ops mt753 +@@ -3140,9 +3171,8 @@ static const struct dsa_switch_ops mt753 .port_mirror_del = mt753x_port_mirror_del, .phylink_get_caps = mt753x_phylink_get_caps, .phylink_validate = mt753x_phylink_validate, @@ -274,7 +274,7 @@ Signed-off-by: Paolo Abeni .phylink_mac_link_down = mt753x_phylink_mac_link_down, .phylink_mac_link_up = mt753x_phylink_mac_link_up, .get_mac_eee = mt753x_get_mac_eee, -@@ -3120,36 +3150,34 @@ static const struct dsa_switch_ops mt753 +@@ -3152,36 +3182,34 @@ static const struct dsa_switch_ops mt753 static const struct mt753x_info mt753x_table[] = { [ID_MT7621] = { .id = ID_MT7621, @@ -314,7 +314,7 @@ Signed-off-by: Paolo Abeni }, }; -@@ -3207,7 +3235,7 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3239,7 +3267,7 @@ mt7530_probe(struct mdio_device *mdiodev if (!priv->info->sw_setup || !priv->info->pad_setup || !priv->info->phy_read || !priv->info->phy_write || !priv->info->mac_port_get_caps || diff --git a/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch b/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch index 4aa013aad79..7b2fa36699b 100644 --- a/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch +++ b/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch @@ -20,7 +20,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2921,25 +2921,16 @@ static void mt753x_phylink_get_caps(stru +@@ -2953,25 +2953,16 @@ static void mt753x_phylink_get_caps(stru priv->info->mac_port_get_caps(ds, port, config); } @@ -55,7 +55,7 @@ Signed-off-by: Paolo Abeni } static void mt7530_pcs_get_state(struct phylink_pcs *pcs, -@@ -3041,12 +3032,14 @@ static void mt7530_pcs_an_restart(struct +@@ -3073,12 +3064,14 @@ static void mt7530_pcs_an_restart(struct } static const struct phylink_pcs_ops mt7530_pcs_ops = { @@ -70,7 +70,7 @@ Signed-off-by: Paolo Abeni .pcs_get_state = mt7531_pcs_get_state, .pcs_config = mt753x_pcs_config, .pcs_an_restart = mt7531_pcs_an_restart, -@@ -3138,7 +3131,6 @@ static const struct dsa_switch_ops mt753 +@@ -3170,7 +3163,6 @@ static const struct dsa_switch_ops mt753 .port_mirror_add = mt753x_port_mirror_add, .port_mirror_del = mt753x_port_mirror_del, .phylink_get_caps = mt753x_phylink_get_caps, diff --git a/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch b/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch index d921d78733d..8bb587f5f57 100644 --- a/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch +++ b/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch @@ -19,7 +19,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2918,6 +2918,12 @@ static void mt753x_phylink_get_caps(stru +@@ -2950,6 +2950,12 @@ static void mt753x_phylink_get_caps(stru config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD; diff --git a/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch b/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch index e797b1ecb42..438c02ade6f 100644 --- a/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch +++ b/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch @@ -81,7 +81,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3056,9 +3056,16 @@ static int +@@ -3088,9 +3088,16 @@ static int mt753x_setup(struct dsa_switch *ds) { struct mt7530_priv *priv = ds->priv; @@ -100,7 +100,7 @@ Signed-off-by: Jakub Kicinski if (ret) return ret; -@@ -3070,13 +3077,6 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3102,13 +3109,6 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); diff --git a/target/linux/generic/backport-5.15/705-12-v6.0-net-dsa-mt7530-rework-mt753-01-_setup.patch b/target/linux/generic/backport-5.15/705-12-v6.0-net-dsa-mt7530-rework-mt753-01-_setup.patch deleted file mode 100644 index b02705cc701..00000000000 --- a/target/linux/generic/backport-5.15/705-12-v6.0-net-dsa-mt7530-rework-mt753-01-_setup.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 1f0dfd443eea7fc3e818e96f7c8264913ba41859 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Fri, 10 Jun 2022 19:05:38 +0200 -Subject: [PATCH 12/13] net: dsa: mt7530: rework mt753[01]_setup - -Enumerate available cpu-ports instead of using hardcoded constant. - -Suggested-by: Vladimir Oltean -Signed-off-by: Frank Wunderlich -Reviewed-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 25 +++++++++++++++++++++---- - 1 file changed, 21 insertions(+), 4 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2101,11 +2101,12 @@ static int - mt7530_setup(struct dsa_switch *ds) - { - struct mt7530_priv *priv = ds->priv; -+ struct device_node *dn = NULL; - struct device_node *phy_node; - struct device_node *mac_np; - struct mt7530_dummy_poll p; - phy_interface_t interface; -- struct device_node *dn; -+ struct dsa_port *cpu_dp; - u32 id, val; - int ret, i; - -@@ -2113,7 +2114,19 @@ mt7530_setup(struct dsa_switch *ds) - * controller also is the container for two GMACs nodes representing - * as two netdev instances. - */ -- dn = dsa_to_port(ds, MT7530_CPU_PORT)->master->dev.of_node->parent; -+ dsa_switch_for_each_cpu_port(cpu_dp, ds) { -+ dn = cpu_dp->master->dev.of_node->parent; -+ /* It doesn't matter which CPU port is found first, -+ * their masters should share the same parent OF node -+ */ -+ break; -+ } -+ -+ if (!dn) { -+ dev_err(ds->dev, "parent OF node of DSA master not found"); -+ return -EINVAL; -+ } -+ - ds->assisted_learning_on_cpu_port = true; - ds->mtu_enforcement_ingress = true; - -@@ -2286,6 +2299,7 @@ mt7531_setup(struct dsa_switch *ds) - { - struct mt7530_priv *priv = ds->priv; - struct mt7530_dummy_poll p; -+ struct dsa_port *cpu_dp; - u32 val, id; - int ret, i; - -@@ -2360,8 +2374,11 @@ mt7531_setup(struct dsa_switch *ds) - CORE_PLL_GROUP4, val); - - /* BPDU to CPU port */ -- mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK, -- BIT(MT7530_CPU_PORT)); -+ dsa_switch_for_each_cpu_port(cpu_dp, ds) { -+ mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK, -+ BIT(cpu_dp->index)); -+ break; -+ } - mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK, - MT753X_BPDU_CPU_ONLY); - diff --git a/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch b/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch index ebfbaccc9d7..377ee76171c 100644 --- a/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch +++ b/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch @@ -19,7 +19,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2721,9 +2721,6 @@ mt7531_mac_config(struct dsa_switch *ds, +@@ -2736,9 +2736,6 @@ mt7531_mac_config(struct dsa_switch *ds, case PHY_INTERFACE_MODE_NA: case PHY_INTERFACE_MODE_1000BASEX: case PHY_INTERFACE_MODE_2500BASEX: @@ -29,7 +29,7 @@ Signed-off-by: David S. Miller return mt7531_sgmii_setup_mode_force(priv, port, interface); default: return -EINVAL; -@@ -2799,13 +2796,6 @@ unsupported: +@@ -2814,13 +2811,6 @@ unsupported: return; } @@ -43,7 +43,7 @@ Signed-off-by: David S. Miller mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port)); mcr_new = mcr_cur; mcr_new &= ~PMCR_LINK_SETTINGS_MASK; -@@ -2942,6 +2932,9 @@ static void mt753x_phylink_get_caps(stru +@@ -2957,6 +2947,9 @@ static void mt753x_phylink_get_caps(stru config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD; @@ -53,7 +53,7 @@ Signed-off-by: David S. Miller /* This driver does not make use of the speed, duplex, pause or the * advertisement in its mac_config, so it is safe to mark this driver * as non-legacy. -@@ -3007,6 +3000,7 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 +@@ -3022,6 +3015,7 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); state->link = !!(status & MT7531_SGMII_LINK_STATUS); @@ -61,7 +61,7 @@ Signed-off-by: David S. Miller if (state->interface == PHY_INTERFACE_MODE_SGMII && (status & MT7531_SGMII_AN_ENABLE)) { val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port)); -@@ -3037,16 +3031,44 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 +@@ -3052,16 +3046,44 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 return 0; } @@ -109,7 +109,7 @@ Signed-off-by: David S. Miller } static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -@@ -3087,6 +3109,8 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3102,6 +3124,8 @@ mt753x_setup(struct dsa_switch *ds) priv->pcs[i].pcs.ops = priv->info->pcs_ops; priv->pcs[i].priv = priv; priv->pcs[i].port = i; diff --git a/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch b/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch index ee12399140b..9e445f1300c 100644 --- a/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch +++ b/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch @@ -81,7 +81,7 @@ Tested-by: Frank Wunderlich #include #include #include -@@ -2573,128 +2574,11 @@ static int mt7531_rgmii_setup(struct mt7 +@@ -2588,128 +2589,11 @@ static int mt7531_rgmii_setup(struct mt7 return 0; } @@ -210,7 +210,7 @@ Tested-by: Frank Wunderlich static int mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode, phy_interface_t interface) -@@ -2717,11 +2601,11 @@ mt7531_mac_config(struct dsa_switch *ds, +@@ -2732,11 +2616,11 @@ mt7531_mac_config(struct dsa_switch *ds, phydev = dp->slave->phydev; return mt7531_rgmii_setup(priv, port, interface, phydev); case PHY_INTERFACE_MODE_SGMII: @@ -224,7 +224,7 @@ Tested-by: Frank Wunderlich default: return -EINVAL; } -@@ -2746,11 +2630,11 @@ mt753x_phylink_mac_select_pcs(struct dsa +@@ -2761,11 +2645,11 @@ mt753x_phylink_mac_select_pcs(struct dsa switch (interface) { case PHY_INTERFACE_MODE_TRGMII: @@ -238,7 +238,7 @@ Tested-by: Frank Wunderlich default: return NULL; } -@@ -2991,86 +2875,6 @@ static void mt7530_pcs_get_state(struct +@@ -3006,86 +2890,6 @@ static void mt7530_pcs_get_state(struct state->pause |= MLO_PAUSE_TX; } @@ -325,7 +325,7 @@ Tested-by: Frank Wunderlich static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode, phy_interface_t interface, const unsigned long *advertising, -@@ -3090,18 +2894,57 @@ static const struct phylink_pcs_ops mt75 +@@ -3105,18 +2909,57 @@ static const struct phylink_pcs_ops mt75 .pcs_an_restart = mt7530_pcs_an_restart, }; @@ -389,7 +389,7 @@ Tested-by: Frank Wunderlich int i, ret; /* Initialise the PCS devices */ -@@ -3109,8 +2952,6 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3124,8 +2967,6 @@ mt753x_setup(struct dsa_switch *ds) priv->pcs[i].pcs.ops = priv->info->pcs_ops; priv->pcs[i].priv = priv; priv->pcs[i].port = i; @@ -398,7 +398,7 @@ Tested-by: Frank Wunderlich } ret = priv->info->sw_setup(ds); -@@ -3125,6 +2966,16 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3140,6 +2981,16 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); @@ -415,7 +415,7 @@ Tested-by: Frank Wunderlich return ret; } -@@ -3216,7 +3067,7 @@ static const struct mt753x_info mt753x_t +@@ -3231,7 +3082,7 @@ static const struct mt753x_info mt753x_t }, [ID_MT7531] = { .id = ID_MT7531, @@ -424,7 +424,7 @@ Tested-by: Frank Wunderlich .sw_setup = mt7531_setup, .phy_read = mt7531_ind_phy_read, .phy_write = mt7531_ind_phy_write, -@@ -3324,7 +3175,7 @@ static void +@@ -3339,7 +3190,7 @@ static void mt7530_remove(struct mdio_device *mdiodev) { struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); @@ -433,7 +433,7 @@ Tested-by: Frank Wunderlich if (!priv) return; -@@ -3343,6 +3194,10 @@ mt7530_remove(struct mdio_device *mdiode +@@ -3358,6 +3209,10 @@ mt7530_remove(struct mdio_device *mdiode mt7530_free_irq(priv); dsa_unregister_switch(priv->ds); diff --git a/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch b/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch index 8963d93d107..a933d376c88 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch @@ -18,7 +18,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2926,26 +2926,56 @@ static const struct regmap_bus mt7531_re +@@ -2941,26 +2941,56 @@ static const struct regmap_bus mt7531_re .reg_update_bits = mt7530_regmap_update_bits, }; @@ -88,7 +88,7 @@ Signed-off-by: David S. Miller int i, ret; /* Initialise the PCS devices */ -@@ -2967,15 +2997,11 @@ mt753x_setup(struct dsa_switch *ds) +@@ -2982,15 +3012,11 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); diff --git a/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch b/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch index 1b4a9561992..5f6990f1178 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch @@ -19,7 +19,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2899,7 +2899,7 @@ static int mt7530_regmap_read(void *cont +@@ -2914,7 +2914,7 @@ static int mt7530_regmap_read(void *cont { struct mt7530_priv *priv = context; @@ -28,7 +28,7 @@ Signed-off-by: David S. Miller return 0; }; -@@ -2907,23 +2907,25 @@ static int mt7530_regmap_write(void *con +@@ -2922,23 +2922,25 @@ static int mt7530_regmap_write(void *con { struct mt7530_priv *priv = context; @@ -62,7 +62,7 @@ Signed-off-by: David S. Miller }; static int -@@ -2949,6 +2951,9 @@ mt7531_create_sgmii(struct mt7530_priv * +@@ -2964,6 +2966,9 @@ mt7531_create_sgmii(struct mt7530_priv * mt7531_pcs_config[i]->reg_stride = 4; mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i); mt7531_pcs_config[i]->max_register = 0x17c; diff --git a/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch b/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch index 2d8bab9da63..9499ca598fb 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch @@ -133,7 +133,7 @@ Signed-off-by: David S. Miller } static void -@@ -2895,22 +2916,6 @@ static const struct phylink_pcs_ops mt75 +@@ -2910,22 +2931,6 @@ static const struct phylink_pcs_ops mt75 .pcs_an_restart = mt7530_pcs_an_restart, }; @@ -156,7 +156,7 @@ Signed-off-by: David S. Miller static void mt7530_mdio_regmap_lock(void *mdio_lock) { -@@ -2923,7 +2928,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc +@@ -2938,7 +2943,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc mutex_unlock(mdio_lock); } @@ -165,7 +165,7 @@ Signed-off-by: David S. Miller .reg_write = mt7530_regmap_write, .reg_read = mt7530_regmap_read, }; -@@ -2956,7 +2961,7 @@ mt7531_create_sgmii(struct mt7530_priv * +@@ -2971,7 +2976,7 @@ mt7531_create_sgmii(struct mt7530_priv * mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock; regmap = devm_regmap_init(priv->dev, @@ -174,7 +174,7 @@ Signed-off-by: David S. Miller mt7531_pcs_config[i]); if (IS_ERR(regmap)) { ret = PTR_ERR(regmap); -@@ -3121,6 +3126,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match) +@@ -3136,6 +3141,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match) static int mt7530_probe(struct mdio_device *mdiodev) { @@ -182,7 +182,7 @@ Signed-off-by: David S. Miller struct mt7530_priv *priv; struct device_node *dn; -@@ -3200,6 +3206,21 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3215,6 +3221,21 @@ mt7530_probe(struct mdio_device *mdiodev mutex_init(&priv->reg_mutex); dev_set_drvdata(&mdiodev->dev, priv); diff --git a/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch b/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch index 0bb64c3c5e9..44c31a4f6f2 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch @@ -18,7 +18,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3007,12 +3007,6 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3022,12 +3022,6 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); @@ -31,7 +31,7 @@ Signed-off-by: David S. Miller return ret; } -@@ -3129,6 +3123,7 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3144,6 +3138,7 @@ mt7530_probe(struct mdio_device *mdiodev static struct regmap_config *regmap_config; struct mt7530_priv *priv; struct device_node *dn; @@ -39,7 +39,7 @@ Signed-off-by: David S. Miller dn = mdiodev->dev.of_node; -@@ -3221,6 +3216,12 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3236,6 +3231,12 @@ mt7530_probe(struct mdio_device *mdiodev if (IS_ERR(priv->regmap)) return PTR_ERR(priv->regmap); diff --git a/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch b/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch index 34a1bd7372d..aeb1e37a1a1 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch @@ -17,7 +17,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3135,44 +3135,21 @@ static const struct of_device_id mt7530_ +@@ -3150,44 +3150,21 @@ static const struct of_device_id mt7530_ MODULE_DEVICE_TABLE(of, mt7530_of_match); static int @@ -67,7 +67,7 @@ Signed-off-by: David S. Miller if (!priv->info) return -EINVAL; -@@ -3186,23 +3163,53 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3201,23 +3178,53 @@ mt7530_probe(struct mdio_device *mdiodev return -EINVAL; priv->id = priv->info->id; @@ -131,7 +131,7 @@ Signed-off-by: David S. Miller priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(priv->reset)) { -@@ -3211,12 +3218,15 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3226,12 +3233,15 @@ mt7530_probe(struct mdio_device *mdiodev } } diff --git a/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch b/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch index 2881365ec77..2651f459183 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch @@ -17,7 +17,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3253,6 +3253,17 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3268,6 +3268,17 @@ mt7530_probe(struct mdio_device *mdiodev } static void @@ -35,7 +35,7 @@ Signed-off-by: David S. Miller mt7530_remove(struct mdio_device *mdiodev) { struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); -@@ -3271,16 +3282,11 @@ mt7530_remove(struct mdio_device *mdiode +@@ -3286,16 +3297,11 @@ mt7530_remove(struct mdio_device *mdiode dev_err(priv->dev, "Failed to disable io pwr: %d\n", ret); diff --git a/target/linux/generic/backport-5.15/790-v6.4-0010-net-dsa-mt7530-split-off-common-parts-from-mt7531_se.patch b/target/linux/generic/backport-5.15/790-v6.4-0010-net-dsa-mt7530-split-off-common-parts-from-mt7531_se.patch deleted file mode 100644 index c8e7d93026d..00000000000 --- a/target/linux/generic/backport-5.15/790-v6.4-0010-net-dsa-mt7530-split-off-common-parts-from-mt7531_se.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 7f54cc9772ced2d76ac11832f0ada43798443ac9 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:19:02 +0100 -Subject: [PATCH 13/16] net: dsa: mt7530: split-off common parts from - mt7531_setup - -MT7988 shares a significant part of the setup function with MT7531. -Split-off those parts into a shared function which is going to be used -also by mt7988_setup. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 99 ++++++++++++++++++++++------------------ - 1 file changed, 55 insertions(+), 44 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2348,11 +2348,64 @@ mt7530_setup(struct dsa_switch *ds) - } - - static int -+mt7531_setup_common(struct dsa_switch *ds) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ struct dsa_port *cpu_dp; -+ int ret, i; -+ -+ /* BPDU to CPU port */ -+ dsa_switch_for_each_cpu_port(cpu_dp, ds) { -+ mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK, -+ BIT(cpu_dp->index)); -+ break; -+ } -+ mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK, -+ MT753X_BPDU_CPU_ONLY); -+ -+ /* Enable and reset MIB counters */ -+ mt7530_mib_reset(ds); -+ -+ for (i = 0; i < MT7530_NUM_PORTS; i++) { -+ /* Disable forwarding by default on all ports */ -+ mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK, -+ PCR_MATRIX_CLR); -+ -+ /* Disable learning by default on all ports */ -+ mt7530_set(priv, MT7530_PSC_P(i), SA_DIS); -+ -+ mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR); -+ -+ if (dsa_is_cpu_port(ds, i)) { -+ ret = mt753x_cpu_port_enable(ds, i); -+ if (ret) -+ return ret; -+ } else { -+ mt7530_port_disable(ds, i); -+ -+ /* Set default PVID to 0 on all user ports */ -+ mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK, -+ G0_PORT_VID_DEF); -+ } -+ -+ /* Enable consistent egress tag */ -+ mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK, -+ PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT)); -+ } -+ -+ /* Flush the FDB table */ -+ ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int - mt7531_setup(struct dsa_switch *ds) - { - struct mt7530_priv *priv = ds->priv; - struct mt7530_dummy_poll p; -- struct dsa_port *cpu_dp; - u32 val, id; - int ret, i; - -@@ -2426,44 +2479,7 @@ mt7531_setup(struct dsa_switch *ds) - mt7531_ind_c45_phy_write(priv, MT753X_CTRL_PHY_ADDR, MDIO_MMD_VEND2, - CORE_PLL_GROUP4, val); - -- /* BPDU to CPU port */ -- dsa_switch_for_each_cpu_port(cpu_dp, ds) { -- mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK, -- BIT(cpu_dp->index)); -- break; -- } -- mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK, -- MT753X_BPDU_CPU_ONLY); -- -- /* Enable and reset MIB counters */ -- mt7530_mib_reset(ds); -- -- for (i = 0; i < MT7530_NUM_PORTS; i++) { -- /* Disable forwarding by default on all ports */ -- mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK, -- PCR_MATRIX_CLR); -- -- /* Disable learning by default on all ports */ -- mt7530_set(priv, MT7530_PSC_P(i), SA_DIS); -- -- mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR); -- -- if (dsa_is_cpu_port(ds, i)) { -- ret = mt753x_cpu_port_enable(ds, i); -- if (ret) -- return ret; -- } else { -- mt7530_port_disable(ds, i); -- -- /* Set default PVID to 0 on all user ports */ -- mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK, -- G0_PORT_VID_DEF); -- } -- -- /* Enable consistent egress tag */ -- mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK, -- PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT)); -- } -+ mt7531_setup_common(ds); - - /* Setup VLAN ID 0 for VLAN-unaware bridges */ - ret = mt7530_setup_vlan0(priv); -@@ -2473,11 +2489,6 @@ mt7531_setup(struct dsa_switch *ds) - ds->assisted_learning_on_cpu_port = true; - ds->mtu_enforcement_ingress = true; - -- /* Flush the FDB table */ -- ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL); -- if (ret < 0) -- return ret; -- - return 0; - } - diff --git a/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch b/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch index 96afa041aad..51346d0620d 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch @@ -416,7 +416,7 @@ Signed-off-by: David S. Miller static u32 mt7530_mii_read(struct mt7530_priv *priv, u32 reg) { -@@ -2944,72 +2895,6 @@ static const struct phylink_pcs_ops mt75 +@@ -2948,72 +2899,6 @@ static const struct phylink_pcs_ops mt75 .pcs_an_restart = mt7530_pcs_an_restart, }; @@ -489,7 +489,7 @@ Signed-off-by: David S. Miller static int mt753x_setup(struct dsa_switch *ds) { -@@ -3068,7 +2953,7 @@ static int mt753x_set_mac_eee(struct dsa +@@ -3072,7 +2957,7 @@ static int mt753x_set_mac_eee(struct dsa return 0; } @@ -498,7 +498,7 @@ Signed-off-by: David S. Miller .get_tag_protocol = mtk_get_tag_protocol, .setup = mt753x_setup, .get_strings = mt7530_get_strings, -@@ -3102,8 +2987,9 @@ static const struct dsa_switch_ops mt753 +@@ -3106,8 +2991,9 @@ static const struct dsa_switch_ops mt753 .get_mac_eee = mt753x_get_mac_eee, .set_mac_eee = mt753x_set_mac_eee, }; @@ -509,7 +509,7 @@ Signed-off-by: David S. Miller [ID_MT7621] = { .id = ID_MT7621, .pcs_ops = &mt7530_pcs_ops, -@@ -3136,16 +3022,9 @@ static const struct mt753x_info mt753x_t +@@ -3140,16 +3026,9 @@ static const struct mt753x_info mt753x_t .mac_port_config = mt7531_mac_config, }, }; @@ -528,7 +528,7 @@ Signed-off-by: David S. Miller mt7530_probe_common(struct mt7530_priv *priv) { struct device *dev = priv->dev; -@@ -3182,88 +3061,9 @@ mt7530_probe_common(struct mt7530_priv * +@@ -3186,88 +3065,9 @@ mt7530_probe_common(struct mt7530_priv * return 0; } @@ -619,7 +619,7 @@ Signed-off-by: David S. Miller mt7530_remove_common(struct mt7530_priv *priv) { if (priv->irq) -@@ -3274,57 +3074,6 @@ mt7530_remove_common(struct mt7530_priv +@@ -3278,57 +3078,6 @@ mt7530_remove_common(struct mt7530_priv mutex_destroy(&priv->reg_mutex); } diff --git a/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch b/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch index 8210aae27ce..00f4b25c44e 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch @@ -250,7 +250,7 @@ Signed-off-by: David S. Miller if (!priv->irq_domain) { dev_err(dev, "failed to create IRQ domain\n"); return -ENOMEM; -@@ -2507,6 +2555,25 @@ static void mt7531_mac_port_get_caps(str +@@ -2511,6 +2559,25 @@ static void mt7531_mac_port_get_caps(str } } @@ -276,7 +276,7 @@ Signed-off-by: David S. Miller static int mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state) { -@@ -2583,6 +2650,17 @@ static bool mt753x_is_mac_port(u32 port) +@@ -2587,6 +2654,17 @@ static bool mt753x_is_mac_port(u32 port) } static int @@ -294,7 +294,7 @@ Signed-off-by: David S. Miller mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode, phy_interface_t interface) { -@@ -2652,7 +2730,8 @@ mt753x_phylink_mac_config(struct dsa_swi +@@ -2656,7 +2734,8 @@ mt753x_phylink_mac_config(struct dsa_swi switch (port) { case 0 ... 4: /* Internal phy */ @@ -304,7 +304,7 @@ Signed-off-by: David S. Miller goto unsupported; break; case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ -@@ -2730,7 +2809,8 @@ static void mt753x_phylink_mac_link_up(s +@@ -2734,7 +2813,8 @@ static void mt753x_phylink_mac_link_up(s /* MT753x MAC works in 1G full duplex mode for all up-clocked * variants. */ @@ -314,7 +314,7 @@ Signed-off-by: David S. Miller (phy_interface_mode_is_8023z(interface))) { speed = SPEED_1000; duplex = DUPLEX_FULL; -@@ -2810,6 +2890,21 @@ mt7531_cpu_port_config(struct dsa_switch +@@ -2814,6 +2894,21 @@ mt7531_cpu_port_config(struct dsa_switch return 0; } @@ -336,7 +336,7 @@ Signed-off-by: David S. Miller static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port, struct phylink_config *config) { -@@ -2955,6 +3050,27 @@ static int mt753x_set_mac_eee(struct dsa +@@ -2959,6 +3054,27 @@ static int mt753x_set_mac_eee(struct dsa return 0; } @@ -364,7 +364,7 @@ Signed-off-by: David S. Miller const struct dsa_switch_ops mt7530_switch_ops = { .get_tag_protocol = mtk_get_tag_protocol, .setup = mt753x_setup, -@@ -3023,6 +3139,17 @@ const struct mt753x_info mt753x_table[] +@@ -3027,6 +3143,17 @@ const struct mt753x_info mt753x_table[] .mac_port_get_caps = mt7531_mac_port_get_caps, .mac_port_config = mt7531_mac_config, }, diff --git a/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch b/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch index 5259730996d..ed8bca7d1c1 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch @@ -73,7 +73,7 @@ Signed-off-by: Jakub Kicinski } --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3017,6 +3017,12 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3021,6 +3021,12 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); diff --git a/target/linux/generic/backport-5.15/807-v6.1-0005-nvmem-prefix-all-symbols-with-NVMEM_.patch b/target/linux/generic/backport-5.15/807-v6.1-0005-nvmem-prefix-all-symbols-with-NVMEM_.patch index ae02439bd73..4410fc4d615 100644 --- a/target/linux/generic/backport-5.15/807-v6.1-0005-nvmem-prefix-all-symbols-with-NVMEM_.patch +++ b/target/linux/generic/backport-5.15/807-v6.1-0005-nvmem-prefix-all-symbols-with-NVMEM_.patch @@ -28,7 +28,7 @@ Signed-off-by: Greg Kroah-Hartman --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig -@@ -1125,10 +1125,10 @@ CONFIG_TI_PIPE3=y +@@ -1124,10 +1124,10 @@ CONFIG_TI_PIPE3=y CONFIG_TWL4030_USB=m CONFIG_RAS=y CONFIG_NVMEM_IMX_OCOTP=y diff --git a/target/linux/generic/backport-6.1/300-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch b/target/linux/generic/backport-6.1/300-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch new file mode 100644 index 00000000000..d8d0cf95557 --- /dev/null +++ b/target/linux/generic/backport-6.1/300-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch @@ -0,0 +1,63 @@ +From 579aee9fc594af94c242068c011b0233563d4bbf Mon Sep 17 00:00:00 2001 +From: Stephen Rothwell +Date: Mon, 10 Oct 2022 16:57:21 +1100 +Subject: [PATCH] powerpc: suppress some linker warnings in recent linker + versions + +This is a follow on from commit + + 0d362be5b142 ("Makefile: link with -z noexecstack --no-warn-rwx-segments") + +for arch/powerpc/boot to address wanrings like: + + ld: warning: opal-calls.o: missing .note.GNU-stack section implies executable stack + ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker + ld: warning: arch/powerpc/boot/zImage.epapr has a LOAD segment with RWX permissions + +This fixes issue https://github.com/linuxppc/issues/issues/417 + +Signed-off-by: Stephen Rothwell +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20221010165721.106267e6@canb.auug.org.au +--- + arch/powerpc/boot/wrapper | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/boot/wrapper ++++ b/arch/powerpc/boot/wrapper +@@ -215,6 +215,11 @@ ld_version() + }' + } + ++ld_is_lld() ++{ ++ ${CROSS}ld -V 2>&1 | grep -q LLD ++} ++ + # Do not include PT_INTERP segment when linking pie. Non-pie linking + # just ignores this option. + LD_VERSION=$(${CROSS}ld --version | ld_version) +@@ -223,6 +228,14 @@ if [ "$LD_VERSION" -ge "$LD_NO_DL_MIN_VE + nodl="--no-dynamic-linker" + fi + ++# suppress some warnings in recent ld versions ++nowarn="-z noexecstack" ++if ! ld_is_lld; then ++ if [ "$LD_VERSION" -ge "$(echo 2.39 | ld_version)" ]; then ++ nowarn="$nowarn --no-warn-rwx-segments" ++ fi ++fi ++ + platformo=$object/"$platform".o + lds=$object/zImage.lds + ext=strip +@@ -504,7 +517,7 @@ if [ "$platform" != "miboot" ]; then + text_start="-Ttext $link_address" + fi + #link everything +- ${CROSS}ld -m $format -T $lds $text_start $pie $nodl $rodynamic $notext -o "$ofile" $map \ ++ ${CROSS}ld -m $format -T $lds $text_start $pie $nodl $nowarn $rodynamic $notext -o "$ofile" $map \ + $platformo $tmp $object/wrapper.a + rm $tmp + fi diff --git a/target/linux/generic/config-5.15 b/target/linux/generic/config-5.15 index 5ca1ff08335..251a6fbcc32 100644 --- a/target/linux/generic/config-5.15 +++ b/target/linux/generic/config-5.15 @@ -1634,6 +1634,7 @@ CONFIG_DQL=y # CONFIG_DRM_RADEON_USERPTR is not set # CONFIG_DRM_RCAR_DW_HDMI is not set # CONFIG_DRM_RCAR_LVDS is not set +# CONFIG_DRM_RCAR_USE_LVDS is not set # CONFIG_DRM_ROCKCHIP is not set # CONFIG_DRM_SII902X is not set # CONFIG_DRM_SII9234 is not set diff --git a/target/linux/generic/config-6.1 b/target/linux/generic/config-6.1 index b0a9277513b..6252e668965 100644 --- a/target/linux/generic/config-6.1 +++ b/target/linux/generic/config-6.1 @@ -150,7 +150,6 @@ CONFIG_AF_UNIX_OOB=y # CONFIG_AHCI_BRCM is not set # CONFIG_AHCI_CEVA is not set # CONFIG_AHCI_DWC is not set -# CONFIG_SATA_DWC_OLD_DMA is not set # CONFIG_AHCI_IMX is not set # CONFIG_AHCI_MVEBU is not set # CONFIG_AHCI_QORIQ is not set @@ -1279,6 +1278,7 @@ CONFIG_CRYPTO_PCRYPT=y # CONFIG_CRYPTO_POLY1305_MIPS is not set # CONFIG_CRYPTO_POLY1305_NEON is not set # CONFIG_CRYPTO_POLY1305_X86_64 is not set +# CONFIG_CRYPTO_POLYVAL_ARM64_CE is not set # CONFIG_CRYPTO_RMD160 is not set # CONFIG_CRYPTO_RNG is not set # CONFIG_CRYPTO_RSA is not set @@ -1311,6 +1311,8 @@ CONFIG_CRYPTO_SKCIPHER2=y # CONFIG_CRYPTO_SM3_NEON is not set # CONFIG_CRYPTO_SM4 is not set # CONFIG_CRYPTO_SM4_ARM64_CE is not set +# CONFIG_CRYPTO_SM4_ARM64_CE_BLK is not set +# CONFIG_CRYPTO_SM4_ARM64_NEON_BLK is not set # CONFIG_CRYPTO_SM4_GENERIC is not set # CONFIG_CRYPTO_SPECK is not set # CONFIG_CRYPTO_STATS is not set @@ -1606,7 +1608,6 @@ CONFIG_DQL=y # CONFIG_DRM_I2C_NXP_TDA998X is not set # CONFIG_DRM_I2C_SIL164 is not set # CONFIG_DRM_I915 is not set -# CONFIG_DRM_ITE_IT6505 is not set # CONFIG_DRM_IMX_LCDIF is not set # CONFIG_DRM_ITE_IT6505 is not set # CONFIG_DRM_ITE_IT66121 is not set @@ -4910,6 +4911,7 @@ CONFIG_PINMUX=y # CONFIG_PM_AUTOSLEEP is not set # CONFIG_PM_DEBUG is not set # CONFIG_PM_DEVFREQ is not set +# CONFIG_PM_USERSPACE_AUTOSLEEP is not set # CONFIG_PM_WAKELOCKS is not set # CONFIG_POSIX_MQUEUE is not set CONFIG_POSIX_TIMERS=y @@ -5407,6 +5409,7 @@ CONFIG_RXKAD=y # CONFIG_SATA_AHCI is not set # CONFIG_SATA_AHCI_PLATFORM is not set # CONFIG_SATA_DWC is not set +# CONFIG_SATA_DWC_OLD_DMA is not set # CONFIG_SATA_FSL is not set # CONFIG_SATA_HIGHBANK is not set # CONFIG_SATA_HOST is not set @@ -7034,6 +7037,7 @@ CONFIG_UNIX98_PTYS=y # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_UNIX_DIAG is not set CONFIG_UNIX_SCM=y +# CONFIG_UNUSED_BOARD_FILES is not set # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_UNWINDER_FRAME_POINTER is not set # CONFIG_UPROBES is not set diff --git a/target/linux/generic/hack-5.15/259-regmap_dynamic.patch b/target/linux/generic/hack-5.15/259-regmap_dynamic.patch index 76a5ace6f31..e0820ccfc0d 100644 --- a/target/linux/generic/hack-5.15/259-regmap_dynamic.patch +++ b/target/linux/generic/hack-5.15/259-regmap_dynamic.patch @@ -125,7 +125,7 @@ Signed-off-by: Felix Fietkau #include #include #include -@@ -3358,3 +3359,5 @@ static int __init regmap_initcall(void) +@@ -3360,3 +3361,5 @@ static int __init regmap_initcall(void) return 0; } postcore_initcall(regmap_initcall); diff --git a/target/linux/generic/hack-5.15/600-bridge_offload.patch b/target/linux/generic/hack-5.15/600-bridge_offload.patch deleted file mode 100644 index 9d71a741b25..00000000000 --- a/target/linux/generic/hack-5.15/600-bridge_offload.patch +++ /dev/null @@ -1,846 +0,0 @@ -From 11c3fae5afa6cac444d12622e2cf5af60a99c1ef Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:43:15 +0200 -Subject: [PATCH] net/bridge: add bridge offload - ---- - include/linux/if_bridge.h | 1 + - net/bridge/Makefile | 2 +- - net/bridge/br.c | 8 + - net/bridge/br_device.c | 2 + - net/bridge/br_fdb.c | 5 + - net/bridge/br_forward.c | 3 + - net/bridge/br_if.c | 6 +- - net/bridge/br_input.c | 5 + - net/bridge/br_offload.c | 438 ++++++++++++++++++++++++++++++++ - net/bridge/br_private.h | 22 +- - net/bridge/br_private_offload.h | 23 ++ - net/bridge/br_stp.c | 3 + - net/bridge/br_sysfs_br.c | 35 +++ - net/bridge/br_sysfs_if.c | 2 + - net/bridge/br_vlan_tunnel.c | 3 + - 15 files changed, 555 insertions(+), 3 deletions(-) - create mode 100644 net/bridge/br_offload.c - create mode 100644 net/bridge/br_private_offload.h - ---- a/include/linux/if_bridge.h -+++ b/include/linux/if_bridge.h -@@ -59,6 +59,7 @@ struct br_ip_list { - #define BR_MRP_LOST_IN_CONT BIT(19) - #define BR_TX_FWD_OFFLOAD BIT(20) - #define BR_BPDU_FILTER BIT(21) -+#define BR_OFFLOAD BIT(22) - - #define BR_DEFAULT_AGEING_TIME (300 * HZ) - ---- a/net/bridge/Makefile -+++ b/net/bridge/Makefile -@@ -5,7 +5,7 @@ - - obj-$(CONFIG_BRIDGE) += bridge.o - --bridge-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o \ -+bridge-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o br_offload.o \ - br_ioctl.o br_stp.o br_stp_bpdu.o \ - br_stp_if.o br_stp_timer.o br_netlink.o \ - br_netlink_tunnel.o br_arp_nd_proxy.o ---- a/net/bridge/br.c -+++ b/net/bridge/br.c -@@ -18,6 +18,7 @@ - #include - - #include "br_private.h" -+#include "br_private_offload.h" - - /* - * Handle changes in state of network devices enslaved to a bridge. -@@ -381,6 +382,10 @@ static int __init br_init(void) - if (err) - goto err_out; - -+ err = br_offload_init(); -+ if (err) -+ goto err_out0; -+ - err = register_pernet_subsys(&br_net_ops); - if (err) - goto err_out1; -@@ -430,6 +435,8 @@ err_out3: - err_out2: - unregister_pernet_subsys(&br_net_ops); - err_out1: -+ br_offload_fini(); -+err_out0: - br_fdb_fini(); - err_out: - stp_proto_unregister(&br_stp_proto); -@@ -452,6 +459,7 @@ static void __exit br_deinit(void) - #if IS_ENABLED(CONFIG_ATM_LANE) - br_fdb_test_addr_hook = NULL; - #endif -+ br_offload_fini(); - br_fdb_fini(); - } - ---- a/net/bridge/br_device.c -+++ b/net/bridge/br_device.c -@@ -524,6 +524,8 @@ void br_dev_setup(struct net_device *dev - br->bridge_hello_time = br->hello_time = 2 * HZ; - br->bridge_forward_delay = br->forward_delay = 15 * HZ; - br->bridge_ageing_time = br->ageing_time = BR_DEFAULT_AGEING_TIME; -+ br->offload_cache_size = 128; -+ br->offload_cache_reserved = 8; - dev->max_mtu = ETH_MAX_MTU; - - br_netfilter_rtable_init(br); ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -23,6 +23,7 @@ - #include - #include - #include "br_private.h" -+#include "br_private_offload.h" - - static const struct rhashtable_params br_fdb_rht_params = { - .head_offset = offsetof(struct net_bridge_fdb_entry, rhnode), -@@ -518,6 +519,8 @@ static struct net_bridge_fdb_entry *fdb_ - fdb->key.vlan_id = vid; - fdb->flags = flags; - fdb->updated = fdb->used = jiffies; -+ INIT_HLIST_HEAD(&fdb->offload_in); -+ INIT_HLIST_HEAD(&fdb->offload_out); - if (rhashtable_lookup_insert_fast(&br->fdb_hash_tbl, - &fdb->rhnode, - br_fdb_rht_params)) { -@@ -794,6 +797,8 @@ static void fdb_notify(struct net_bridge - struct sk_buff *skb; - int err = -ENOBUFS; - -+ br_offload_fdb_update(fdb); -+ - if (swdev_notify) - br_switchdev_fdb_notify(br, fdb, type); - ---- a/net/bridge/br_forward.c -+++ b/net/bridge/br_forward.c -@@ -16,6 +16,7 @@ - #include - #include - #include "br_private.h" -+#include "br_private_offload.h" - - /* Don't forward packets to originating port or forwarding disabled */ - static inline int should_deliver(const struct net_bridge_port *p, -@@ -32,6 +33,8 @@ static inline int should_deliver(const s - - int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb) - { -+ br_offload_output(skb); -+ - skb_push(skb, ETH_HLEN); - if (!is_skb_forwardable(skb->dev, skb)) - goto drop; ---- a/net/bridge/br_if.c -+++ b/net/bridge/br_if.c -@@ -25,6 +25,7 @@ - #include - - #include "br_private.h" -+#include "br_private_offload.h" - - /* - * Determine initial path cost based on speed. -@@ -428,7 +429,7 @@ static struct net_bridge_port *new_nbp(s - p->path_cost = port_cost(dev); - p->priority = 0x8000 >> BR_PORT_BITS; - p->port_no = index; -- p->flags = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; -+ p->flags = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD | BR_OFFLOAD; - br_init_port(p); - br_set_state(p, BR_STATE_DISABLED); - br_stp_port_timer_init(p); -@@ -771,6 +772,9 @@ void br_port_flags_change(struct net_bri - - if (mask & BR_NEIGH_SUPPRESS) - br_recalculate_neigh_suppress_enabled(br); -+ -+ if (mask & BR_OFFLOAD) -+ br_offload_port_state(p); - } - - bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag) ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -22,6 +22,7 @@ - #include - #include "br_private.h" - #include "br_private_tunnel.h" -+#include "br_private_offload.h" - - static int - br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb) -@@ -171,6 +172,7 @@ int br_handle_frame_finish(struct net *n - dst->used = now; - br_forward(dst->dst, skb, local_rcv, false); - } else { -+ br_offload_skb_disable(skb); - if (!mcast_hit) - br_flood(br, skb, pkt_type, local_rcv, false); - else -@@ -304,6 +306,9 @@ static rx_handler_result_t br_handle_fra - memset(skb->cb, 0, sizeof(struct br_input_skb_cb)); - - p = br_port_get_rcu(skb->dev); -+ if (br_offload_input(p, skb)) -+ return RX_HANDLER_CONSUMED; -+ - if (p->flags & BR_VLAN_TUNNEL) - br_handle_ingress_vlan_tunnel(skb, p, nbp_vlan_group_rcu(p)); - ---- /dev/null -+++ b/net/bridge/br_offload.c -@@ -0,0 +1,438 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+#include -+#include -+#include "br_private.h" -+#include "br_private_offload.h" -+ -+static DEFINE_SPINLOCK(offload_lock); -+ -+struct bridge_flow_key { -+ u8 dest[ETH_ALEN]; -+ u8 src[ETH_ALEN]; -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ u16 vlan_tag; -+ bool vlan_present; -+#endif -+}; -+ -+struct bridge_flow { -+ struct net_bridge_port *port; -+ struct rhash_head node; -+ struct bridge_flow_key key; -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ bool vlan_out_present; -+ u16 vlan_out; -+#endif -+ -+ unsigned long used; -+ struct net_bridge_fdb_entry *fdb_in, *fdb_out; -+ struct hlist_node fdb_list_in, fdb_list_out; -+ -+ struct rcu_head rcu; -+}; -+ -+static const struct rhashtable_params flow_params = { -+ .automatic_shrinking = true, -+ .head_offset = offsetof(struct bridge_flow, node), -+ .key_len = sizeof(struct bridge_flow_key), -+ .key_offset = offsetof(struct bridge_flow, key), -+}; -+ -+static struct kmem_cache *offload_cache __read_mostly; -+ -+static void -+flow_rcu_free(struct rcu_head *head) -+{ -+ struct bridge_flow *flow; -+ -+ flow = container_of(head, struct bridge_flow, rcu); -+ kmem_cache_free(offload_cache, flow); -+} -+ -+static void -+__br_offload_flow_free(struct bridge_flow *flow) -+{ -+ flow->used = 0; -+ hlist_del(&flow->fdb_list_in); -+ hlist_del(&flow->fdb_list_out); -+ -+ call_rcu(&flow->rcu, flow_rcu_free); -+} -+ -+static void -+br_offload_flow_free(struct bridge_flow *flow) -+{ -+ if (rhashtable_remove_fast(&flow->port->offload.rht, &flow->node, -+ flow_params) != 0) -+ return; -+ -+ __br_offload_flow_free(flow); -+} -+ -+static bool -+br_offload_flow_fdb_refresh_time(struct bridge_flow *flow, -+ struct net_bridge_fdb_entry *fdb) -+{ -+ if (!time_after(flow->used, fdb->updated)) -+ return false; -+ -+ fdb->updated = flow->used; -+ -+ return true; -+} -+ -+ -+static void -+br_offload_flow_refresh_time(struct bridge_flow *flow) -+{ -+ br_offload_flow_fdb_refresh_time(flow, flow->fdb_in); -+ br_offload_flow_fdb_refresh_time(flow, flow->fdb_out); -+} -+ -+static void -+br_offload_destroy_cb(void *ptr, void *arg) -+{ -+ struct bridge_flow *flow = ptr; -+ -+ __br_offload_flow_free(flow); -+} -+ -+static bool -+br_offload_need_gc(struct net_bridge_port *p) -+{ -+ return (atomic_read(&p->offload.rht.nelems) + -+ p->br->offload_cache_reserved) >= p->br->offload_cache_size; -+} -+ -+static void -+br_offload_gc_work(struct work_struct *work) -+{ -+ struct rhashtable_iter hti; -+ struct net_bridge_port *p; -+ struct bridge_flow *gc_flow = NULL; -+ struct bridge_flow *flow; -+ unsigned long gc_used; -+ -+ p = container_of(work, struct net_bridge_port, offload.gc_work); -+ -+ if (!br_offload_need_gc(p)) -+ return; -+ -+ rhashtable_walk_enter(&p->offload.rht, &hti); -+ rhashtable_walk_start(&hti); -+ while ((flow = rhashtable_walk_next(&hti)) != NULL) { -+ unsigned long used; -+ -+ if (IS_ERR(flow)) -+ continue; -+ -+ used = READ_ONCE(flow->used); -+ if (!used) -+ continue; -+ -+ if (gc_flow && !time_before(used, gc_used)) -+ continue; -+ -+ gc_flow = flow; -+ gc_used = used; -+ } -+ rhashtable_walk_stop(&hti); -+ rhashtable_walk_exit(&hti); -+ -+ if (!gc_flow) -+ return; -+ -+ spin_lock_bh(&offload_lock); -+ if (br_offload_need_gc(p) && gc_flow && -+ gc_flow->used == gc_used) -+ br_offload_flow_free(gc_flow); -+ if (p->offload.enabled && br_offload_need_gc(p)) -+ queue_work(system_long_wq, work); -+ spin_unlock_bh(&offload_lock); -+ -+} -+ -+void br_offload_port_state(struct net_bridge_port *p) -+{ -+ struct net_bridge_port_offload *o = &p->offload; -+ bool enabled = true; -+ bool flush = false; -+ -+ if (p->state != BR_STATE_FORWARDING || -+ !(p->flags & BR_OFFLOAD)) -+ enabled = false; -+ -+ spin_lock_bh(&offload_lock); -+ if (o->enabled == enabled) -+ goto out; -+ -+ if (enabled) { -+ if (!o->gc_work.func) -+ INIT_WORK(&o->gc_work, br_offload_gc_work); -+ rhashtable_init(&o->rht, &flow_params); -+ } else { -+ flush = true; -+ rhashtable_free_and_destroy(&o->rht, br_offload_destroy_cb, o); -+ } -+ -+ o->enabled = enabled; -+ -+out: -+ spin_unlock_bh(&offload_lock); -+ -+ if (flush) -+ flush_work(&o->gc_work); -+} -+ -+void br_offload_fdb_update(const struct net_bridge_fdb_entry *fdb) -+{ -+ struct bridge_flow *f; -+ struct hlist_node *tmp; -+ -+ spin_lock_bh(&offload_lock); -+ -+ hlist_for_each_entry_safe(f, tmp, &fdb->offload_in, fdb_list_in) -+ br_offload_flow_free(f); -+ -+ hlist_for_each_entry_safe(f, tmp, &fdb->offload_out, fdb_list_out) -+ br_offload_flow_free(f); -+ -+ spin_unlock_bh(&offload_lock); -+} -+ -+static void -+br_offload_prepare_key(struct net_bridge_port *p, struct bridge_flow_key *key, -+ struct sk_buff *skb) -+{ -+ memset(key, 0, sizeof(*key)); -+ memcpy(key, eth_hdr(skb), 2 * ETH_ALEN); -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ if (!br_opt_get(p->br, BROPT_VLAN_ENABLED)) -+ return; -+ -+ if (!skb_vlan_tag_present(skb) || skb->vlan_proto != p->br->vlan_proto) -+ return; -+ -+ key->vlan_present = true; -+ key->vlan_tag = skb_vlan_tag_get_id(skb); -+#endif -+} -+ -+void br_offload_output(struct sk_buff *skb) -+{ -+ struct net_bridge_port_offload *o; -+ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb; -+ struct net_bridge_port *p, *inp; -+ struct net_device *dev; -+ struct net_bridge_fdb_entry *fdb_in, *fdb_out; -+ struct net_bridge_vlan_group *vg; -+ struct bridge_flow_key key; -+ struct bridge_flow *flow; -+ u16 vlan; -+ -+ if (!cb->offload) -+ return; -+ -+ rcu_read_lock(); -+ -+ p = br_port_get_rcu(skb->dev); -+ if (!p) -+ goto out; -+ -+ o = &p->offload; -+ if (!o->enabled) -+ goto out; -+ -+ if (atomic_read(&p->offload.rht.nelems) >= p->br->offload_cache_size) -+ goto out; -+ -+ dev = dev_get_by_index_rcu(dev_net(p->br->dev), cb->input_ifindex); -+ if (!dev) -+ goto out; -+ -+ inp = br_port_get_rcu(dev); -+ if (!inp) -+ goto out; -+ -+ vg = nbp_vlan_group_rcu(inp); -+ vlan = cb->input_vlan_present ? cb->input_vlan_tag : br_get_pvid(vg); -+ fdb_in = br_fdb_find_rcu(p->br, eth_hdr(skb)->h_source, vlan); -+ if (!fdb_in || !fdb_in->dst) -+ goto out; -+ -+ vg = nbp_vlan_group_rcu(p); -+ vlan = skb_vlan_tag_present(skb) ? skb_vlan_tag_get_id(skb) : br_get_pvid(vg); -+ fdb_out = br_fdb_find_rcu(p->br, eth_hdr(skb)->h_dest, vlan); -+ if (!fdb_out || !fdb_out->dst) -+ goto out; -+ -+ br_offload_prepare_key(p, &key, skb); -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ key.vlan_present = cb->input_vlan_present; -+ key.vlan_tag = cb->input_vlan_tag; -+#endif -+ -+ flow = kmem_cache_alloc(offload_cache, GFP_ATOMIC); -+ flow->port = inp; -+ memcpy(&flow->key, &key, sizeof(key)); -+ -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ flow->vlan_out_present = skb_vlan_tag_present(skb); -+ flow->vlan_out = skb_vlan_tag_get(skb); -+#endif -+ -+ flow->fdb_in = fdb_in; -+ flow->fdb_out = fdb_out; -+ flow->used = jiffies; -+ -+ spin_lock_bh(&offload_lock); -+ if (!o->enabled || -+ atomic_read(&p->offload.rht.nelems) >= p->br->offload_cache_size || -+ rhashtable_insert_fast(&inp->offload.rht, &flow->node, flow_params)) { -+ kmem_cache_free(offload_cache, flow); -+ goto out_unlock; -+ } -+ -+ hlist_add_head(&flow->fdb_list_in, &fdb_in->offload_in); -+ hlist_add_head(&flow->fdb_list_out, &fdb_out->offload_out); -+ -+ if (br_offload_need_gc(p)) -+ queue_work(system_long_wq, &p->offload.gc_work); -+ -+out_unlock: -+ spin_unlock_bh(&offload_lock); -+ -+out: -+ rcu_read_unlock(); -+} -+ -+bool br_offload_input(struct net_bridge_port *p, struct sk_buff *skb) -+{ -+ struct net_bridge_port_offload *o = &p->offload; -+ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb; -+ struct bridge_flow_key key; -+ struct net_bridge_port *dst; -+ struct bridge_flow *flow; -+ unsigned long now = jiffies; -+ bool ret = false; -+ -+ if (skb->len < sizeof(key)) -+ return false; -+ -+ if (!o->enabled) -+ return false; -+ -+ if (is_multicast_ether_addr(eth_hdr(skb)->h_dest)) -+ return false; -+ -+ br_offload_prepare_key(p, &key, skb); -+ -+ rcu_read_lock(); -+ flow = rhashtable_lookup(&o->rht, &key, flow_params); -+ if (!flow) { -+ cb->offload = 1; -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ cb->input_vlan_present = key.vlan_present != 0; -+ cb->input_vlan_tag = key.vlan_tag; -+#endif -+ cb->input_ifindex = p->dev->ifindex; -+ goto out; -+ } -+ -+ if (flow->fdb_in->dst != p) -+ goto out; -+ -+ dst = flow->fdb_out->dst; -+ if (!dst) -+ goto out; -+ -+ ret = true; -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ if (!flow->vlan_out_present && key.vlan_present) { -+ __vlan_hwaccel_clear_tag(skb); -+ } else if (flow->vlan_out_present) { -+ if (skb_vlan_tag_present(skb) && -+ skb->vlan_proto != p->br->vlan_proto) { -+ /* Protocol-mismatch, empty out vlan_tci for new tag */ -+ skb_push(skb, ETH_HLEN); -+ skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, -+ skb_vlan_tag_get(skb)); -+ if (unlikely(!skb)) -+ goto out; -+ -+ skb_pull(skb, ETH_HLEN); -+ skb_reset_mac_len(skb); -+ } -+ -+ __vlan_hwaccel_put_tag(skb, p->br->vlan_proto, -+ flow->vlan_out); -+ } -+#endif -+ -+ skb->dev = dst->dev; -+ skb_push(skb, ETH_HLEN); -+ -+ if (skb_warn_if_lro(skb) || !is_skb_forwardable(skb->dev, skb)) { -+ kfree_skb(skb); -+ goto out; -+ } -+ -+ if (now - flow->used >= HZ) { -+ flow->used = now; -+ br_offload_flow_refresh_time(flow); -+ } -+ -+ skb_forward_csum(skb); -+ dev_queue_xmit(skb); -+ -+out: -+ rcu_read_unlock(); -+ return ret; -+} -+ -+static void -+br_offload_check_gc(struct net_bridge *br) -+{ -+ struct net_bridge_port *p; -+ -+ spin_lock_bh(&br->lock); -+ list_for_each_entry(p, &br->port_list, list) -+ if (br_offload_need_gc(p)) -+ queue_work(system_long_wq, &p->offload.gc_work); -+ spin_unlock_bh(&br->lock); -+} -+ -+ -+int br_offload_set_cache_size(struct net_bridge *br, unsigned long val, -+ struct netlink_ext_ack *extack) -+{ -+ br->offload_cache_size = val; -+ br_offload_check_gc(br); -+ -+ return 0; -+} -+ -+int br_offload_set_cache_reserved(struct net_bridge *br, unsigned long val, -+ struct netlink_ext_ack *extack) -+{ -+ br->offload_cache_reserved = val; -+ br_offload_check_gc(br); -+ -+ return 0; -+} -+ -+int __init br_offload_init(void) -+{ -+ offload_cache = kmem_cache_create("bridge_offload_cache", -+ sizeof(struct bridge_flow), -+ 0, SLAB_HWCACHE_ALIGN, NULL); -+ if (!offload_cache) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+void br_offload_fini(void) -+{ -+ kmem_cache_destroy(offload_cache); -+} ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -268,7 +268,13 @@ struct net_bridge_fdb_entry { - unsigned long updated ____cacheline_aligned_in_smp; - unsigned long used; - -- struct rcu_head rcu; -+ union { -+ struct { -+ struct hlist_head offload_in; -+ struct hlist_head offload_out; -+ }; -+ struct rcu_head rcu; -+ }; - }; - - #define MDB_PG_FLAGS_PERMANENT BIT(0) -@@ -343,6 +349,12 @@ struct net_bridge_mdb_entry { - struct rcu_head rcu; - }; - -+struct net_bridge_port_offload { -+ struct rhashtable rht; -+ struct work_struct gc_work; -+ bool enabled; -+}; -+ - struct net_bridge_port { - struct net_bridge *br; - struct net_device *dev; -@@ -403,6 +415,7 @@ struct net_bridge_port { - u16 backup_redirected_cnt; - - struct bridge_stp_xstats stp_xstats; -+ struct net_bridge_port_offload offload; - }; - - #define kobj_to_brport(obj) container_of(obj, struct net_bridge_port, kobj) -@@ -519,6 +532,9 @@ struct net_bridge { - struct kobject *ifobj; - u32 auto_cnt; - -+ u32 offload_cache_size; -+ u32 offload_cache_reserved; -+ - #ifdef CONFIG_NET_SWITCHDEV - /* Counter used to make sure that hardware domains get unique - * identifiers in case a bridge spans multiple switchdev instances. -@@ -553,6 +569,10 @@ struct br_input_skb_cb { - #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE - u8 br_netfilter_broute:1; - #endif -+ u8 offload:1; -+ u8 input_vlan_present:1; -+ u16 input_vlan_tag; -+ int input_ifindex; - - #ifdef CONFIG_NET_SWITCHDEV - /* Set if TX data plane offloading is used towards at least one ---- /dev/null -+++ b/net/bridge/br_private_offload.h -@@ -0,0 +1,23 @@ -+#ifndef __BR_OFFLOAD_H -+#define __BR_OFFLOAD_H -+ -+bool br_offload_input(struct net_bridge_port *p, struct sk_buff *skb); -+void br_offload_output(struct sk_buff *skb); -+void br_offload_port_state(struct net_bridge_port *p); -+void br_offload_fdb_update(const struct net_bridge_fdb_entry *fdb); -+int br_offload_init(void); -+void br_offload_fini(void); -+int br_offload_set_cache_size(struct net_bridge *br, unsigned long val, -+ struct netlink_ext_ack *extack); -+int br_offload_set_cache_reserved(struct net_bridge *br, unsigned long val, -+ struct netlink_ext_ack *extack); -+ -+static inline void br_offload_skb_disable(struct sk_buff *skb) -+{ -+ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb; -+ -+ if (cb->offload) -+ cb->offload = 0; -+} -+ -+#endif ---- a/net/bridge/br_stp.c -+++ b/net/bridge/br_stp.c -@@ -12,6 +12,7 @@ - - #include "br_private.h" - #include "br_private_stp.h" -+#include "br_private_offload.h" - - /* since time values in bpdu are in jiffies and then scaled (1/256) - * before sending, make sure that is at least one STP tick. -@@ -52,6 +53,8 @@ void br_set_state(struct net_bridge_port - (unsigned int) p->port_no, p->dev->name, - br_port_state_names[p->state]); - -+ br_offload_port_state(p); -+ - if (p->br->stp_enabled == BR_KERNEL_STP) { - switch (p->state) { - case BR_STATE_BLOCKING: ---- a/net/bridge/br_sysfs_br.c -+++ b/net/bridge/br_sysfs_br.c -@@ -18,6 +18,7 @@ - #include - - #include "br_private.h" -+#include "br_private_offload.h" - - /* IMPORTANT: new bridge options must be added with netlink support only - * please do not add new sysfs entries -@@ -930,6 +931,38 @@ static ssize_t vlan_stats_per_port_store - static DEVICE_ATTR_RW(vlan_stats_per_port); - #endif - -+static ssize_t offload_cache_size_show(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct net_bridge *br = to_bridge(d); -+ return sprintf(buf, "%u\n", br->offload_cache_size); -+} -+ -+static ssize_t offload_cache_size_store(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t len) -+{ -+ return store_bridge_parm(d, buf, len, br_offload_set_cache_size); -+} -+static DEVICE_ATTR_RW(offload_cache_size); -+ -+static ssize_t offload_cache_reserved_show(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct net_bridge *br = to_bridge(d); -+ return sprintf(buf, "%u\n", br->offload_cache_reserved); -+} -+ -+static ssize_t offload_cache_reserved_store(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t len) -+{ -+ return store_bridge_parm(d, buf, len, br_offload_set_cache_reserved); -+} -+static DEVICE_ATTR_RW(offload_cache_reserved); -+ - static struct attribute *bridge_attrs[] = { - &dev_attr_forward_delay.attr, - &dev_attr_hello_time.attr, -@@ -984,6 +1017,8 @@ static struct attribute *bridge_attrs[] - &dev_attr_vlan_stats_enabled.attr, - &dev_attr_vlan_stats_per_port.attr, - #endif -+ &dev_attr_offload_cache_size.attr, -+ &dev_attr_offload_cache_reserved.attr, - NULL - }; - ---- a/net/bridge/br_sysfs_if.c -+++ b/net/bridge/br_sysfs_if.c -@@ -241,6 +241,7 @@ BRPORT_ATTR_FLAG(broadcast_flood, BR_BCA - BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS); - BRPORT_ATTR_FLAG(isolated, BR_ISOLATED); - BRPORT_ATTR_FLAG(bpdu_filter, BR_BPDU_FILTER); -+BRPORT_ATTR_FLAG(offload, BR_OFFLOAD); - - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) -@@ -295,6 +296,7 @@ static const struct brport_attribute *br - &brport_attr_isolated, - &brport_attr_bpdu_filter, - &brport_attr_backup_port, -+ &brport_attr_offload, - NULL - }; - ---- a/net/bridge/br_vlan_tunnel.c -+++ b/net/bridge/br_vlan_tunnel.c -@@ -15,6 +15,7 @@ - - #include "br_private.h" - #include "br_private_tunnel.h" -+#include "br_private_offload.h" - - static inline int br_vlan_tunid_cmp(struct rhashtable_compare_arg *arg, - const void *ptr) -@@ -180,6 +181,7 @@ void br_handle_ingress_vlan_tunnel(struc - skb_dst_drop(skb); - - __vlan_hwaccel_put_tag(skb, p->br->vlan_proto, vlan->vid); -+ br_offload_skb_disable(skb); - } - - int br_handle_egress_vlan_tunnel(struct sk_buff *skb, -@@ -201,6 +203,7 @@ int br_handle_egress_vlan_tunnel(struct - if (err) - return err; - -+ br_offload_skb_disable(skb); - tunnel_dst = rcu_dereference(vlan->tinfo.tunnel_dst); - if (tunnel_dst && dst_hold_safe(&tunnel_dst->dst)) - skb_dst_set(skb, &tunnel_dst->dst); diff --git a/target/linux/generic/hack-6.1/259-regmap_dynamic.patch b/target/linux/generic/hack-6.1/259-regmap_dynamic.patch index 407bc72ac8d..8d25f59ce28 100644 --- a/target/linux/generic/hack-6.1/259-regmap_dynamic.patch +++ b/target/linux/generic/hack-6.1/259-regmap_dynamic.patch @@ -125,7 +125,7 @@ Signed-off-by: Felix Fietkau #include #include #include -@@ -3511,3 +3512,5 @@ static int __init regmap_initcall(void) +@@ -3513,3 +3514,5 @@ static int __init regmap_initcall(void) return 0; } postcore_initcall(regmap_initcall); diff --git a/target/linux/generic/hack-6.1/600-bridge_offload.patch b/target/linux/generic/hack-6.1/600-bridge_offload.patch deleted file mode 100644 index aa78c96e7f1..00000000000 --- a/target/linux/generic/hack-6.1/600-bridge_offload.patch +++ /dev/null @@ -1,846 +0,0 @@ -From 11c3fae5afa6cac444d12622e2cf5af60a99c1ef Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:43:15 +0200 -Subject: [PATCH] net/bridge: add bridge offload - ---- - include/linux/if_bridge.h | 1 + - net/bridge/Makefile | 2 +- - net/bridge/br.c | 8 + - net/bridge/br_device.c | 2 + - net/bridge/br_fdb.c | 5 + - net/bridge/br_forward.c | 3 + - net/bridge/br_if.c | 6 +- - net/bridge/br_input.c | 5 + - net/bridge/br_offload.c | 438 ++++++++++++++++++++++++++++++++ - net/bridge/br_private.h | 22 +- - net/bridge/br_private_offload.h | 23 ++ - net/bridge/br_stp.c | 3 + - net/bridge/br_sysfs_br.c | 35 +++ - net/bridge/br_sysfs_if.c | 2 + - net/bridge/br_vlan_tunnel.c | 3 + - 15 files changed, 555 insertions(+), 3 deletions(-) - create mode 100644 net/bridge/br_offload.c - create mode 100644 net/bridge/br_private_offload.h - ---- a/include/linux/if_bridge.h -+++ b/include/linux/if_bridge.h -@@ -60,6 +60,7 @@ struct br_ip_list { - #define BR_TX_FWD_OFFLOAD BIT(20) - #define BR_PORT_LOCKED BIT(21) - #define BR_BPDU_FILTER BIT(22) -+#define BR_OFFLOAD BIT(23) - - #define BR_DEFAULT_AGEING_TIME (300 * HZ) - ---- a/net/bridge/Makefile -+++ b/net/bridge/Makefile -@@ -5,7 +5,7 @@ - - obj-$(CONFIG_BRIDGE) += bridge.o - --bridge-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o \ -+bridge-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o br_offload.o \ - br_ioctl.o br_stp.o br_stp_bpdu.o \ - br_stp_if.o br_stp_timer.o br_netlink.o \ - br_netlink_tunnel.o br_arp_nd_proxy.o ---- a/net/bridge/br.c -+++ b/net/bridge/br.c -@@ -18,6 +18,7 @@ - #include - - #include "br_private.h" -+#include "br_private_offload.h" - - /* - * Handle changes in state of network devices enslaved to a bridge. -@@ -389,6 +390,10 @@ static int __init br_init(void) - if (err) - goto err_out; - -+ err = br_offload_init(); -+ if (err) -+ goto err_out0; -+ - err = register_pernet_subsys(&br_net_ops); - if (err) - goto err_out1; -@@ -438,6 +443,8 @@ err_out3: - err_out2: - unregister_pernet_subsys(&br_net_ops); - err_out1: -+ br_offload_fini(); -+err_out0: - br_fdb_fini(); - err_out: - stp_proto_unregister(&br_stp_proto); -@@ -460,6 +467,7 @@ static void __exit br_deinit(void) - #if IS_ENABLED(CONFIG_ATM_LANE) - br_fdb_test_addr_hook = NULL; - #endif -+ br_offload_fini(); - br_fdb_fini(); - } - ---- a/net/bridge/br_device.c -+++ b/net/bridge/br_device.c -@@ -525,6 +525,8 @@ void br_dev_setup(struct net_device *dev - br->bridge_hello_time = br->hello_time = 2 * HZ; - br->bridge_forward_delay = br->forward_delay = 15 * HZ; - br->bridge_ageing_time = br->ageing_time = BR_DEFAULT_AGEING_TIME; -+ br->offload_cache_size = 128; -+ br->offload_cache_reserved = 8; - dev->max_mtu = ETH_MAX_MTU; - - br_netfilter_rtable_init(br); ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -23,6 +23,7 @@ - #include - #include - #include "br_private.h" -+#include "br_private_offload.h" - - static const struct rhashtable_params br_fdb_rht_params = { - .head_offset = offsetof(struct net_bridge_fdb_entry, rhnode), -@@ -185,6 +186,8 @@ static void fdb_notify(struct net_bridge - struct sk_buff *skb; - int err = -ENOBUFS; - -+ br_offload_fdb_update(fdb); -+ - if (swdev_notify) - br_switchdev_fdb_notify(br, fdb, type); - -@@ -393,6 +396,8 @@ static struct net_bridge_fdb_entry *fdb_ - fdb->key.vlan_id = vid; - fdb->flags = flags; - fdb->updated = fdb->used = jiffies; -+ INIT_HLIST_HEAD(&fdb->offload_in); -+ INIT_HLIST_HEAD(&fdb->offload_out); - err = rhashtable_lookup_insert_fast(&br->fdb_hash_tbl, &fdb->rhnode, - br_fdb_rht_params); - if (err) { ---- a/net/bridge/br_forward.c -+++ b/net/bridge/br_forward.c -@@ -16,6 +16,7 @@ - #include - #include - #include "br_private.h" -+#include "br_private_offload.h" - - /* Don't forward packets to originating port or forwarding disabled */ - static inline int should_deliver(const struct net_bridge_port *p, -@@ -32,6 +33,8 @@ static inline int should_deliver(const s - - int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb) - { -+ br_offload_output(skb); -+ - skb_push(skb, ETH_HLEN); - if (!is_skb_forwardable(skb->dev, skb)) - goto drop; ---- a/net/bridge/br_if.c -+++ b/net/bridge/br_if.c -@@ -25,6 +25,7 @@ - #include - - #include "br_private.h" -+#include "br_private_offload.h" - - /* - * Determine initial path cost based on speed. -@@ -437,7 +438,7 @@ static struct net_bridge_port *new_nbp(s - p->path_cost = port_cost(dev); - p->priority = 0x8000 >> BR_PORT_BITS; - p->port_no = index; -- p->flags = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; -+ p->flags = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD | BR_OFFLOAD; - br_init_port(p); - br_set_state(p, BR_STATE_DISABLED); - br_stp_port_timer_init(p); -@@ -761,6 +762,9 @@ void br_port_flags_change(struct net_bri - - if (mask & BR_NEIGH_SUPPRESS) - br_recalculate_neigh_suppress_enabled(br); -+ -+ if (mask & BR_OFFLOAD) -+ br_offload_port_state(p); - } - - bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag) ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -22,6 +22,7 @@ - #include - #include "br_private.h" - #include "br_private_tunnel.h" -+#include "br_private_offload.h" - - static int - br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb) -@@ -189,6 +190,7 @@ int br_handle_frame_finish(struct net *n - dst->used = now; - br_forward(dst->dst, skb, local_rcv, false); - } else { -+ br_offload_skb_disable(skb); - if (!mcast_hit) - br_flood(br, skb, pkt_type, local_rcv, false); - else -@@ -322,6 +324,9 @@ static rx_handler_result_t br_handle_fra - memset(skb->cb, 0, sizeof(struct br_input_skb_cb)); - - p = br_port_get_rcu(skb->dev); -+ if (br_offload_input(p, skb)) -+ return RX_HANDLER_CONSUMED; -+ - if (p->flags & BR_VLAN_TUNNEL) - br_handle_ingress_vlan_tunnel(skb, p, nbp_vlan_group_rcu(p)); - ---- /dev/null -+++ b/net/bridge/br_offload.c -@@ -0,0 +1,438 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+#include -+#include -+#include "br_private.h" -+#include "br_private_offload.h" -+ -+static DEFINE_SPINLOCK(offload_lock); -+ -+struct bridge_flow_key { -+ u8 dest[ETH_ALEN]; -+ u8 src[ETH_ALEN]; -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ u16 vlan_tag; -+ bool vlan_present; -+#endif -+}; -+ -+struct bridge_flow { -+ struct net_bridge_port *port; -+ struct rhash_head node; -+ struct bridge_flow_key key; -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ bool vlan_out_present; -+ u16 vlan_out; -+#endif -+ -+ unsigned long used; -+ struct net_bridge_fdb_entry *fdb_in, *fdb_out; -+ struct hlist_node fdb_list_in, fdb_list_out; -+ -+ struct rcu_head rcu; -+}; -+ -+static const struct rhashtable_params flow_params = { -+ .automatic_shrinking = true, -+ .head_offset = offsetof(struct bridge_flow, node), -+ .key_len = sizeof(struct bridge_flow_key), -+ .key_offset = offsetof(struct bridge_flow, key), -+}; -+ -+static struct kmem_cache *offload_cache __read_mostly; -+ -+static void -+flow_rcu_free(struct rcu_head *head) -+{ -+ struct bridge_flow *flow; -+ -+ flow = container_of(head, struct bridge_flow, rcu); -+ kmem_cache_free(offload_cache, flow); -+} -+ -+static void -+__br_offload_flow_free(struct bridge_flow *flow) -+{ -+ flow->used = 0; -+ hlist_del(&flow->fdb_list_in); -+ hlist_del(&flow->fdb_list_out); -+ -+ call_rcu(&flow->rcu, flow_rcu_free); -+} -+ -+static void -+br_offload_flow_free(struct bridge_flow *flow) -+{ -+ if (rhashtable_remove_fast(&flow->port->offload.rht, &flow->node, -+ flow_params) != 0) -+ return; -+ -+ __br_offload_flow_free(flow); -+} -+ -+static bool -+br_offload_flow_fdb_refresh_time(struct bridge_flow *flow, -+ struct net_bridge_fdb_entry *fdb) -+{ -+ if (!time_after(flow->used, fdb->updated)) -+ return false; -+ -+ fdb->updated = flow->used; -+ -+ return true; -+} -+ -+ -+static void -+br_offload_flow_refresh_time(struct bridge_flow *flow) -+{ -+ br_offload_flow_fdb_refresh_time(flow, flow->fdb_in); -+ br_offload_flow_fdb_refresh_time(flow, flow->fdb_out); -+} -+ -+static void -+br_offload_destroy_cb(void *ptr, void *arg) -+{ -+ struct bridge_flow *flow = ptr; -+ -+ __br_offload_flow_free(flow); -+} -+ -+static bool -+br_offload_need_gc(struct net_bridge_port *p) -+{ -+ return (atomic_read(&p->offload.rht.nelems) + -+ p->br->offload_cache_reserved) >= p->br->offload_cache_size; -+} -+ -+static void -+br_offload_gc_work(struct work_struct *work) -+{ -+ struct rhashtable_iter hti; -+ struct net_bridge_port *p; -+ struct bridge_flow *gc_flow = NULL; -+ struct bridge_flow *flow; -+ unsigned long gc_used; -+ -+ p = container_of(work, struct net_bridge_port, offload.gc_work); -+ -+ if (!br_offload_need_gc(p)) -+ return; -+ -+ rhashtable_walk_enter(&p->offload.rht, &hti); -+ rhashtable_walk_start(&hti); -+ while ((flow = rhashtable_walk_next(&hti)) != NULL) { -+ unsigned long used; -+ -+ if (IS_ERR(flow)) -+ continue; -+ -+ used = READ_ONCE(flow->used); -+ if (!used) -+ continue; -+ -+ if (gc_flow && !time_before(used, gc_used)) -+ continue; -+ -+ gc_flow = flow; -+ gc_used = used; -+ } -+ rhashtable_walk_stop(&hti); -+ rhashtable_walk_exit(&hti); -+ -+ if (!gc_flow) -+ return; -+ -+ spin_lock_bh(&offload_lock); -+ if (br_offload_need_gc(p) && gc_flow && -+ gc_flow->used == gc_used) -+ br_offload_flow_free(gc_flow); -+ if (p->offload.enabled && br_offload_need_gc(p)) -+ queue_work(system_long_wq, work); -+ spin_unlock_bh(&offload_lock); -+ -+} -+ -+void br_offload_port_state(struct net_bridge_port *p) -+{ -+ struct net_bridge_port_offload *o = &p->offload; -+ bool enabled = true; -+ bool flush = false; -+ -+ if (p->state != BR_STATE_FORWARDING || -+ !(p->flags & BR_OFFLOAD)) -+ enabled = false; -+ -+ spin_lock_bh(&offload_lock); -+ if (o->enabled == enabled) -+ goto out; -+ -+ if (enabled) { -+ if (!o->gc_work.func) -+ INIT_WORK(&o->gc_work, br_offload_gc_work); -+ rhashtable_init(&o->rht, &flow_params); -+ } else { -+ flush = true; -+ rhashtable_free_and_destroy(&o->rht, br_offload_destroy_cb, o); -+ } -+ -+ o->enabled = enabled; -+ -+out: -+ spin_unlock_bh(&offload_lock); -+ -+ if (flush) -+ flush_work(&o->gc_work); -+} -+ -+void br_offload_fdb_update(const struct net_bridge_fdb_entry *fdb) -+{ -+ struct bridge_flow *f; -+ struct hlist_node *tmp; -+ -+ spin_lock_bh(&offload_lock); -+ -+ hlist_for_each_entry_safe(f, tmp, &fdb->offload_in, fdb_list_in) -+ br_offload_flow_free(f); -+ -+ hlist_for_each_entry_safe(f, tmp, &fdb->offload_out, fdb_list_out) -+ br_offload_flow_free(f); -+ -+ spin_unlock_bh(&offload_lock); -+} -+ -+static void -+br_offload_prepare_key(struct net_bridge_port *p, struct bridge_flow_key *key, -+ struct sk_buff *skb) -+{ -+ memset(key, 0, sizeof(*key)); -+ memcpy(key, eth_hdr(skb), 2 * ETH_ALEN); -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ if (!br_opt_get(p->br, BROPT_VLAN_ENABLED)) -+ return; -+ -+ if (!skb_vlan_tag_present(skb) || skb->vlan_proto != p->br->vlan_proto) -+ return; -+ -+ key->vlan_present = true; -+ key->vlan_tag = skb_vlan_tag_get_id(skb); -+#endif -+} -+ -+void br_offload_output(struct sk_buff *skb) -+{ -+ struct net_bridge_port_offload *o; -+ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb; -+ struct net_bridge_port *p, *inp; -+ struct net_device *dev; -+ struct net_bridge_fdb_entry *fdb_in, *fdb_out; -+ struct net_bridge_vlan_group *vg; -+ struct bridge_flow_key key; -+ struct bridge_flow *flow; -+ u16 vlan; -+ -+ if (!cb->offload) -+ return; -+ -+ rcu_read_lock(); -+ -+ p = br_port_get_rcu(skb->dev); -+ if (!p) -+ goto out; -+ -+ o = &p->offload; -+ if (!o->enabled) -+ goto out; -+ -+ if (atomic_read(&p->offload.rht.nelems) >= p->br->offload_cache_size) -+ goto out; -+ -+ dev = dev_get_by_index_rcu(dev_net(p->br->dev), cb->input_ifindex); -+ if (!dev) -+ goto out; -+ -+ inp = br_port_get_rcu(dev); -+ if (!inp) -+ goto out; -+ -+ vg = nbp_vlan_group_rcu(inp); -+ vlan = cb->input_vlan_present ? cb->input_vlan_tag : br_get_pvid(vg); -+ fdb_in = br_fdb_find_rcu(p->br, eth_hdr(skb)->h_source, vlan); -+ if (!fdb_in || !fdb_in->dst) -+ goto out; -+ -+ vg = nbp_vlan_group_rcu(p); -+ vlan = skb_vlan_tag_present(skb) ? skb_vlan_tag_get_id(skb) : br_get_pvid(vg); -+ fdb_out = br_fdb_find_rcu(p->br, eth_hdr(skb)->h_dest, vlan); -+ if (!fdb_out || !fdb_out->dst) -+ goto out; -+ -+ br_offload_prepare_key(p, &key, skb); -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ key.vlan_present = cb->input_vlan_present; -+ key.vlan_tag = cb->input_vlan_tag; -+#endif -+ -+ flow = kmem_cache_alloc(offload_cache, GFP_ATOMIC); -+ flow->port = inp; -+ memcpy(&flow->key, &key, sizeof(key)); -+ -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ flow->vlan_out_present = skb_vlan_tag_present(skb); -+ flow->vlan_out = skb_vlan_tag_get(skb); -+#endif -+ -+ flow->fdb_in = fdb_in; -+ flow->fdb_out = fdb_out; -+ flow->used = jiffies; -+ -+ spin_lock_bh(&offload_lock); -+ if (!o->enabled || -+ atomic_read(&p->offload.rht.nelems) >= p->br->offload_cache_size || -+ rhashtable_insert_fast(&inp->offload.rht, &flow->node, flow_params)) { -+ kmem_cache_free(offload_cache, flow); -+ goto out_unlock; -+ } -+ -+ hlist_add_head(&flow->fdb_list_in, &fdb_in->offload_in); -+ hlist_add_head(&flow->fdb_list_out, &fdb_out->offload_out); -+ -+ if (br_offload_need_gc(p)) -+ queue_work(system_long_wq, &p->offload.gc_work); -+ -+out_unlock: -+ spin_unlock_bh(&offload_lock); -+ -+out: -+ rcu_read_unlock(); -+} -+ -+bool br_offload_input(struct net_bridge_port *p, struct sk_buff *skb) -+{ -+ struct net_bridge_port_offload *o = &p->offload; -+ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb; -+ struct bridge_flow_key key; -+ struct net_bridge_port *dst; -+ struct bridge_flow *flow; -+ unsigned long now = jiffies; -+ bool ret = false; -+ -+ if (skb->len < sizeof(key)) -+ return false; -+ -+ if (!o->enabled) -+ return false; -+ -+ if (is_multicast_ether_addr(eth_hdr(skb)->h_dest)) -+ return false; -+ -+ br_offload_prepare_key(p, &key, skb); -+ -+ rcu_read_lock(); -+ flow = rhashtable_lookup(&o->rht, &key, flow_params); -+ if (!flow) { -+ cb->offload = 1; -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ cb->input_vlan_present = key.vlan_present != 0; -+ cb->input_vlan_tag = key.vlan_tag; -+#endif -+ cb->input_ifindex = p->dev->ifindex; -+ goto out; -+ } -+ -+ if (flow->fdb_in->dst != p) -+ goto out; -+ -+ dst = flow->fdb_out->dst; -+ if (!dst) -+ goto out; -+ -+ ret = true; -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ if (!flow->vlan_out_present && key.vlan_present) { -+ __vlan_hwaccel_clear_tag(skb); -+ } else if (flow->vlan_out_present) { -+ if (skb_vlan_tag_present(skb) && -+ skb->vlan_proto != p->br->vlan_proto) { -+ /* Protocol-mismatch, empty out vlan_tci for new tag */ -+ skb_push(skb, ETH_HLEN); -+ skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, -+ skb_vlan_tag_get(skb)); -+ if (unlikely(!skb)) -+ goto out; -+ -+ skb_pull(skb, ETH_HLEN); -+ skb_reset_mac_len(skb); -+ } -+ -+ __vlan_hwaccel_put_tag(skb, p->br->vlan_proto, -+ flow->vlan_out); -+ } -+#endif -+ -+ skb->dev = dst->dev; -+ skb_push(skb, ETH_HLEN); -+ -+ if (skb_warn_if_lro(skb) || !is_skb_forwardable(skb->dev, skb)) { -+ kfree_skb(skb); -+ goto out; -+ } -+ -+ if (now - flow->used >= HZ) { -+ flow->used = now; -+ br_offload_flow_refresh_time(flow); -+ } -+ -+ skb_forward_csum(skb); -+ dev_queue_xmit(skb); -+ -+out: -+ rcu_read_unlock(); -+ return ret; -+} -+ -+static void -+br_offload_check_gc(struct net_bridge *br) -+{ -+ struct net_bridge_port *p; -+ -+ spin_lock_bh(&br->lock); -+ list_for_each_entry(p, &br->port_list, list) -+ if (br_offload_need_gc(p)) -+ queue_work(system_long_wq, &p->offload.gc_work); -+ spin_unlock_bh(&br->lock); -+} -+ -+ -+int br_offload_set_cache_size(struct net_bridge *br, unsigned long val, -+ struct netlink_ext_ack *extack) -+{ -+ br->offload_cache_size = val; -+ br_offload_check_gc(br); -+ -+ return 0; -+} -+ -+int br_offload_set_cache_reserved(struct net_bridge *br, unsigned long val, -+ struct netlink_ext_ack *extack) -+{ -+ br->offload_cache_reserved = val; -+ br_offload_check_gc(br); -+ -+ return 0; -+} -+ -+int __init br_offload_init(void) -+{ -+ offload_cache = kmem_cache_create("bridge_offload_cache", -+ sizeof(struct bridge_flow), -+ 0, SLAB_HWCACHE_ALIGN, NULL); -+ if (!offload_cache) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+void br_offload_fini(void) -+{ -+ kmem_cache_destroy(offload_cache); -+} ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -271,7 +271,13 @@ struct net_bridge_fdb_entry { - unsigned long updated ____cacheline_aligned_in_smp; - unsigned long used; - -- struct rcu_head rcu; -+ union { -+ struct { -+ struct hlist_head offload_in; -+ struct hlist_head offload_out; -+ }; -+ struct rcu_head rcu; -+ }; - }; - - struct net_bridge_fdb_flush_desc { -@@ -353,6 +359,12 @@ struct net_bridge_mdb_entry { - struct rcu_head rcu; - }; - -+struct net_bridge_port_offload { -+ struct rhashtable rht; -+ struct work_struct gc_work; -+ bool enabled; -+}; -+ - struct net_bridge_port { - struct net_bridge *br; - struct net_device *dev; -@@ -414,6 +426,7 @@ struct net_bridge_port { - u16 backup_redirected_cnt; - - struct bridge_stp_xstats stp_xstats; -+ struct net_bridge_port_offload offload; - }; - - #define kobj_to_brport(obj) container_of(obj, struct net_bridge_port, kobj) -@@ -531,6 +544,9 @@ struct net_bridge { - struct kobject *ifobj; - u32 auto_cnt; - -+ u32 offload_cache_size; -+ u32 offload_cache_reserved; -+ - #ifdef CONFIG_NET_SWITCHDEV - /* Counter used to make sure that hardware domains get unique - * identifiers in case a bridge spans multiple switchdev instances. -@@ -565,6 +581,10 @@ struct br_input_skb_cb { - #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE - u8 br_netfilter_broute:1; - #endif -+ u8 offload:1; -+ u8 input_vlan_present:1; -+ u16 input_vlan_tag; -+ int input_ifindex; - - #ifdef CONFIG_NET_SWITCHDEV - /* Set if TX data plane offloading is used towards at least one ---- /dev/null -+++ b/net/bridge/br_private_offload.h -@@ -0,0 +1,23 @@ -+#ifndef __BR_OFFLOAD_H -+#define __BR_OFFLOAD_H -+ -+bool br_offload_input(struct net_bridge_port *p, struct sk_buff *skb); -+void br_offload_output(struct sk_buff *skb); -+void br_offload_port_state(struct net_bridge_port *p); -+void br_offload_fdb_update(const struct net_bridge_fdb_entry *fdb); -+int br_offload_init(void); -+void br_offload_fini(void); -+int br_offload_set_cache_size(struct net_bridge *br, unsigned long val, -+ struct netlink_ext_ack *extack); -+int br_offload_set_cache_reserved(struct net_bridge *br, unsigned long val, -+ struct netlink_ext_ack *extack); -+ -+static inline void br_offload_skb_disable(struct sk_buff *skb) -+{ -+ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb; -+ -+ if (cb->offload) -+ cb->offload = 0; -+} -+ -+#endif ---- a/net/bridge/br_stp.c -+++ b/net/bridge/br_stp.c -@@ -12,6 +12,7 @@ - - #include "br_private.h" - #include "br_private_stp.h" -+#include "br_private_offload.h" - - /* since time values in bpdu are in jiffies and then scaled (1/256) - * before sending, make sure that is at least one STP tick. -@@ -58,6 +59,8 @@ void br_set_state(struct net_bridge_port - (unsigned int) p->port_no, p->dev->name, - br_port_state_names[p->state]); - -+ br_offload_port_state(p); -+ - if (p->br->stp_enabled == BR_KERNEL_STP) { - switch (p->state) { - case BR_STATE_BLOCKING: ---- a/net/bridge/br_sysfs_br.c -+++ b/net/bridge/br_sysfs_br.c -@@ -18,6 +18,7 @@ - #include - - #include "br_private.h" -+#include "br_private_offload.h" - - /* IMPORTANT: new bridge options must be added with netlink support only - * please do not add new sysfs entries -@@ -933,6 +934,38 @@ static ssize_t vlan_stats_per_port_store - static DEVICE_ATTR_RW(vlan_stats_per_port); - #endif - -+static ssize_t offload_cache_size_show(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct net_bridge *br = to_bridge(d); -+ return sprintf(buf, "%u\n", br->offload_cache_size); -+} -+ -+static ssize_t offload_cache_size_store(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t len) -+{ -+ return store_bridge_parm(d, buf, len, br_offload_set_cache_size); -+} -+static DEVICE_ATTR_RW(offload_cache_size); -+ -+static ssize_t offload_cache_reserved_show(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct net_bridge *br = to_bridge(d); -+ return sprintf(buf, "%u\n", br->offload_cache_reserved); -+} -+ -+static ssize_t offload_cache_reserved_store(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t len) -+{ -+ return store_bridge_parm(d, buf, len, br_offload_set_cache_reserved); -+} -+static DEVICE_ATTR_RW(offload_cache_reserved); -+ - static struct attribute *bridge_attrs[] = { - &dev_attr_forward_delay.attr, - &dev_attr_hello_time.attr, -@@ -987,6 +1020,8 @@ static struct attribute *bridge_attrs[] - &dev_attr_vlan_stats_enabled.attr, - &dev_attr_vlan_stats_per_port.attr, - #endif -+ &dev_attr_offload_cache_size.attr, -+ &dev_attr_offload_cache_reserved.attr, - NULL - }; - ---- a/net/bridge/br_sysfs_if.c -+++ b/net/bridge/br_sysfs_if.c -@@ -241,6 +241,7 @@ BRPORT_ATTR_FLAG(broadcast_flood, BR_BCA - BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS); - BRPORT_ATTR_FLAG(isolated, BR_ISOLATED); - BRPORT_ATTR_FLAG(bpdu_filter, BR_BPDU_FILTER); -+BRPORT_ATTR_FLAG(offload, BR_OFFLOAD); - - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) -@@ -295,6 +296,7 @@ static const struct brport_attribute *br - &brport_attr_isolated, - &brport_attr_bpdu_filter, - &brport_attr_backup_port, -+ &brport_attr_offload, - NULL - }; - ---- a/net/bridge/br_vlan_tunnel.c -+++ b/net/bridge/br_vlan_tunnel.c -@@ -15,6 +15,7 @@ - - #include "br_private.h" - #include "br_private_tunnel.h" -+#include "br_private_offload.h" - - static inline int br_vlan_tunid_cmp(struct rhashtable_compare_arg *arg, - const void *ptr) -@@ -180,6 +181,7 @@ void br_handle_ingress_vlan_tunnel(struc - skb_dst_drop(skb); - - __vlan_hwaccel_put_tag(skb, p->br->vlan_proto, vlan->vid); -+ br_offload_skb_disable(skb); - } - - int br_handle_egress_vlan_tunnel(struct sk_buff *skb, -@@ -201,6 +203,7 @@ int br_handle_egress_vlan_tunnel(struct - if (err) - return err; - -+ br_offload_skb_disable(skb); - tunnel_dst = rcu_dereference(vlan->tinfo.tunnel_dst); - if (tunnel_dst && dst_hold_safe(&tunnel_dst->dst)) - skb_dst_set(skb, &tunnel_dst->dst); diff --git a/target/linux/generic/pending-5.15/203-kallsyms_uncompressed.patch b/target/linux/generic/pending-5.15/203-kallsyms_uncompressed.patch index 930d0ff0fe4..e469b7229ce 100644 --- a/target/linux/generic/pending-5.15/203-kallsyms_uncompressed.patch +++ b/target/linux/generic/pending-5.15/203-kallsyms_uncompressed.patch @@ -33,7 +33,7 @@ Signed-off-by: Felix Fietkau --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c -@@ -80,6 +80,11 @@ static unsigned int kallsyms_expand_symb +@@ -88,6 +88,11 @@ static unsigned int kallsyms_expand_symb * For every byte on the compressed symbol data, copy the table * entry for that byte. */ @@ -45,7 +45,7 @@ Signed-off-by: Felix Fietkau while (len) { tptr = &kallsyms_token_table[kallsyms_token_index[*data]]; data++; -@@ -112,6 +117,9 @@ tail: +@@ -120,6 +125,9 @@ tail: */ static char kallsyms_get_symbol_type(unsigned int off) { @@ -65,7 +65,7 @@ Signed-off-by: Felix Fietkau static int absolute_percpu; static int base_relative; -@@ -486,6 +487,9 @@ static void write_src(void) +@@ -509,6 +510,9 @@ static void write_src(void) free(markers); @@ -75,7 +75,7 @@ Signed-off-by: Felix Fietkau output_label("kallsyms_token_table"); off = 0; for (i = 0; i < 256; i++) { -@@ -537,6 +541,9 @@ static unsigned char *find_token(unsigne +@@ -560,6 +564,9 @@ static unsigned char *find_token(unsigne { int i; @@ -85,7 +85,7 @@ Signed-off-by: Felix Fietkau for (i = 0; i < len - 1; i++) { if (str[i] == token[0] && str[i+1] == token[1]) return &str[i]; -@@ -609,6 +616,9 @@ static void optimize_result(void) +@@ -632,6 +639,9 @@ static void optimize_result(void) { int i, best; @@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau /* using the '\0' symbol last allows compress_symbols to use standard * fast string functions */ for (i = 255; i >= 0; i--) { -@@ -773,6 +783,8 @@ int main(int argc, char **argv) +@@ -796,6 +806,8 @@ int main(int argc, char **argv) absolute_percpu = 1; else if (strcmp(argv[i], "--base-relative") == 0) base_relative = 1; diff --git a/target/linux/generic/pending-5.15/630-packet_socket_type.patch b/target/linux/generic/pending-5.15/630-packet_socket_type.patch index b95ceebac76..ee13ce2a5c8 100644 --- a/target/linux/generic/pending-5.15/630-packet_socket_type.patch +++ b/target/linux/generic/pending-5.15/630-packet_socket_type.patch @@ -87,7 +87,7 @@ Signed-off-by: Felix Fietkau if (!net_eq(dev_net(dev), sock_net(sk))) goto drop; -@@ -3340,6 +3342,7 @@ static int packet_create(struct net *net +@@ -3342,6 +3344,7 @@ static int packet_create(struct net *net mutex_init(&po->pg_vec_lock); po->rollover = NULL; po->prot_hook.func = packet_rcv; @@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau if (sock->type == SOCK_PACKET) po->prot_hook.func = packet_rcv_spkt; -@@ -3977,6 +3980,16 @@ packet_setsockopt(struct socket *sock, i +@@ -3979,6 +3982,16 @@ packet_setsockopt(struct socket *sock, i WRITE_ONCE(po->xmit, val ? packet_direct_xmit : dev_queue_xmit); return 0; } @@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau default: return -ENOPROTOOPT; } -@@ -4033,6 +4046,13 @@ static int packet_getsockopt(struct sock +@@ -4035,6 +4048,13 @@ static int packet_getsockopt(struct sock case PACKET_VNET_HDR: val = po->has_vnet_hdr; break; diff --git a/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch b/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch index 2a2ca7f1fae..7e8ed5455d9 100644 --- a/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch +++ b/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch @@ -161,7 +161,7 @@ Signed-off-by: Felix Fietkau struct rtnl_link { rtnl_doit_func doit; -@@ -4700,7 +4700,9 @@ int ndo_dflt_bridge_getlink(struct sk_bu +@@ -4706,7 +4706,9 @@ int ndo_dflt_bridge_getlink(struct sk_bu brport_nla_put_flag(skb, flags, mask, IFLA_BRPORT_MCAST_FLOOD, BR_MCAST_FLOOD) || brport_nla_put_flag(skb, flags, mask, diff --git a/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch b/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch index bd806a7a6df..a3274906a43 100644 --- a/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch +++ b/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch @@ -10,12 +10,21 @@ The datasheet [1] explicit describes it as requirement for a reset. Signed-off-by: Alexander Couzens --- - drivers/net/dsa/mt7530.c | 4 ++++ - 1 file changed, 4 insertions(+) + drivers/net/dsa/mt7530.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2440,6 +2440,10 @@ mt7531_setup(struct dsa_switch *ds) +@@ -2412,7 +2412,7 @@ mt7531_setup(struct dsa_switch *ds) + struct mt7530_priv *priv = ds->priv; + struct mt7530_dummy_poll p; + u32 val, id; +- int ret; ++ int ret, i; + + /* Reset whole chip through gpio pin or memory-mapped registers for + * different type of hardware +@@ -2444,6 +2444,10 @@ mt7531_setup(struct dsa_switch *ds) return -ENODEV; } diff --git a/target/linux/generic/pending-6.1/630-packet_socket_type.patch b/target/linux/generic/pending-6.1/630-packet_socket_type.patch index 6579dcb4689..8e667fb4dde 100644 --- a/target/linux/generic/pending-6.1/630-packet_socket_type.patch +++ b/target/linux/generic/pending-6.1/630-packet_socket_type.patch @@ -87,7 +87,7 @@ Signed-off-by: Felix Fietkau if (!net_eq(dev_net(dev), sock_net(sk))) goto drop; -@@ -3372,6 +3374,7 @@ static int packet_create(struct net *net +@@ -3374,6 +3376,7 @@ static int packet_create(struct net *net mutex_init(&po->pg_vec_lock); po->rollover = NULL; po->prot_hook.func = packet_rcv; @@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau if (sock->type == SOCK_PACKET) po->prot_hook.func = packet_rcv_spkt; -@@ -4007,6 +4010,16 @@ packet_setsockopt(struct socket *sock, i +@@ -4009,6 +4012,16 @@ packet_setsockopt(struct socket *sock, i WRITE_ONCE(po->xmit, val ? packet_direct_xmit : dev_queue_xmit); return 0; } @@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau default: return -ENOPROTOOPT; } -@@ -4063,6 +4076,13 @@ static int packet_getsockopt(struct sock +@@ -4065,6 +4078,13 @@ static int packet_getsockopt(struct sock case PACKET_VNET_HDR: val = po->has_vnet_hdr; break; diff --git a/target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch b/target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch index 0ecb8703336..7eb3d8653fa 100644 --- a/target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch +++ b/target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch @@ -161,7 +161,7 @@ Signed-off-by: Felix Fietkau struct rtnl_link { rtnl_doit_func doit; -@@ -4811,7 +4811,9 @@ int ndo_dflt_bridge_getlink(struct sk_bu +@@ -4817,7 +4817,9 @@ int ndo_dflt_bridge_getlink(struct sk_bu brport_nla_put_flag(skb, flags, mask, IFLA_BRPORT_MCAST_FLOOD, BR_MCAST_FLOOD) || brport_nla_put_flag(skb, flags, mask, diff --git a/target/linux/ipq807x/Makefile b/target/linux/ipq807x/Makefile index 2f076279b7a..e4342883957 100644 --- a/target/linux/ipq807x/Makefile +++ b/target/linux/ipq807x/Makefile @@ -16,6 +16,7 @@ DEFAULT_PACKAGES += \ kmod-leds-gpio kmod-gpio-button-hotplug \ kmod-phy-aquantia kmod-qca-nss-dp \ ath11k-firmware-ipq8074 kmod-ath11k-ahb \ - wpad-basic-mbedtls uboot-envtools + wpad-basic-mbedtls uboot-envtools \ + e2fsprogs kmod-fs-ext4 losetup $(eval $(call BuildTarget)) diff --git a/target/linux/ipq807x/base-files/etc/board.d/02_network b/target/linux/ipq807x/base-files/etc/board.d/02_network index edd1e131b66..8175a99f97e 100644 --- a/target/linux/ipq807x/base-files/etc/board.d/02_network +++ b/target/linux/ipq807x/base-files/etc/board.d/02_network @@ -25,6 +25,9 @@ ipq807x_setup_interfaces() netgear,wax218) ucidef_set_interface_lan "lan" "dhcp" ;; + prpl,haze) + ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" "wan" + ;; qnap,301w) ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4 10g-2" "10g-1" ;; diff --git a/target/linux/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata b/target/linux/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata index ddb0737d209..f9315573ec4 100644 --- a/target/linux/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata +++ b/target/linux/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata @@ -22,10 +22,17 @@ case "$FIRMWARE" in zyxel,nbg7815) caldata_extract "0:art" 0x1000 0x20000 ;; + prpl,haze) + caldata_extract_mmc "0:ART" 0x1000 0x20000 + ;; esac ;; -"ath11k/QCN9074/hw1.0/cal-pci-0000:01:00.0.bin") +"ath11k/QCN9074/hw1.0/cal-pci-0000:01:00.0.bin"|\ +"ath11k/QCN9074/hw1.0/cal-pci-0001:01:00.0.bin") case "$board" in + prpl,haze) + caldata_extract_mmc "0:ART" 0x26800 0x20000 + ;; xiaomi,ax9000) caldata_extract "0:art" 0x26800 0x20000 ;; diff --git a/target/linux/ipq807x/base-files/lib/upgrade/platform.sh b/target/linux/ipq807x/base-files/lib/upgrade/platform.sh index f7c47723150..458eb16b795 100644 --- a/target/linux/ipq807x/base-files/lib/upgrade/platform.sh +++ b/target/linux/ipq807x/base-files/lib/upgrade/platform.sh @@ -71,6 +71,7 @@ platform_do_upgrade() { netgear,wax218) nand_do_upgrade "$1" ;; + prpl,haze|\ qnap,301w) kernelname="0:HLOS" rootfsname="rootfs" diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts new file mode 100644 index 00000000000..8a5200b4ebf --- /dev/null +++ b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts @@ -0,0 +1,308 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +/dts-v1/; + +#include "ipq8074.dtsi" +#include "ipq8074-hk-cpu.dtsi" +#include "ipq8074-ess.dtsi" +#include +#include +#include + +/ { + model = "prpl Foundation Haze"; + compatible = "prpl,haze", "qcom,ipq8074"; + + aliases { + serial0 = &blsp1_uart5; + /* Aliases are required by U-Boot to patch MAC addresses */ + ethernet0 = &dp6_syn; + ethernet1 = &dp4; + ethernet2 = &dp3; + ethernet3 = &dp2; + label-mac-device = &dp6_syn; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + keys { + compatible = "gpio-keys"; + pinctrl-0 = <&button_pins>; + pinctrl-names = "default"; + + wps-button { + label = "wps"; + gpios = <&tlmm 42 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + reset-button { + label = "reset"; + gpios = <&tlmm 44 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; +}; + +&tlmm { + mdio_pins: mdio-state { + mdc-pins { + pins = "gpio68"; + function = "mdc"; + drive-strength = <8>; + bias-pull-up; + }; + + mdio-pins { + pins = "gpio69"; + function = "mdio"; + drive-strength = <8>; + bias-pull-up; + }; + }; + + button_pins: button-state { + wps-pins { + pins = "gpio42"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + }; + + rst-pins { + pins = "gpio44"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + }; + }; +}; + +&blsp1_uart5 { + status = "okay"; +}; + +&prng { + status = "okay"; +}; + +&ssphy_0 { + status = "okay"; +}; + +&qusb_phy_0 { + status = "okay"; +}; + +&ssphy_1 { + status = "okay"; +}; + +&qusb_phy_1 { + status = "okay"; +}; + +&usb_0 { + status = "okay"; +}; + +&usb_1 { + status = "okay"; +}; + +&cryptobam { + status = "okay"; +}; + +&crypto { + status = "okay"; +}; + +&qpic_bam { + status = "okay"; +}; + +&blsp1_spi1 { /* BLSP1 QUP1 */ + pinctrl-0 = <&spi_0_pins>; + pinctrl-names = "default"; + cs-gpios = <0>; + status = "okay"; + + flash@0 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; + compatible = "jedec,spi-nor"; + spi-max-frequency = <50000000>; + + partitions { + compatible = "qcom,smem-part"; + }; + }; +}; + +&mdio { + status = "okay"; + + pinctrl-0 = <&mdio_pins>; + pinctrl-names = "default"; + reset-gpios = <&tlmm 22 GPIO_ACTIVE_LOW>; + + qca8075_1: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; + + qca8075_2: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; + + qca8075_3: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <2>; + }; + + qca8075_4: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <3>; + }; + + aqr113c: ethernet-phy@5 { + compatible ="ethernet-phy-ieee802.3-c45"; + reg = <8>; + reset-gpios = <&tlmm 43 GPIO_ACTIVE_LOW>; + }; +}; + +&sdhc_1 { + status = "okay"; + + vqmmc-supply = <&l11>; +}; + +&switch { + status = "okay"; + + switch_cpu_bmp = <0x1>; /* cpu port bitmap */ + switch_lan_bmp = <0x1e>; /* lan port bitmap */ + switch_wan_bmp = <0x60>; /* wan port bitmap */ + switch_mac_mode = <0x0>; /* mac mode for uniphy instance0*/ + switch_mac_mode1 = <0xe>; /* mac mode for uniphy instance1*/ + switch_mac_mode2 = <0xd>; /* mac mode for uniphy instance2*/ + bm_tick_mode = <0>; /* bm tick mode */ + tm_tick_mode = <0>; /* tm tick mode */ + + qcom,port_phyinfo { + port@0 { + port_id = <1>; + phy_address = <0>; + }; + port@1 { + port_id = <2>; + phy_address = <1>; + }; + port@2 { + port_id = <3>; + phy_address = <2>; + }; + port@3 { + port_id = <4>; + phy_address = <3>; + }; + port@4 { + port_id = <6>; + phy_address = <8>; + compatible = "ethernet-phy-ieee802.3-c45"; + ethernet-phy-ieee802.3-c45; + }; + }; +}; + +&edma { + status = "okay"; +}; + +/* Dummy LAN port */ +&dp1 { + status = "disabled"; + phy-handle = <&qca8075_1>; + label = "lan4"; +}; + +&dp2 { + status = "okay"; + phy-handle = <&qca8075_2>; + label = "lan3"; +}; + +&dp3 { + status = "okay"; + phy-handle = <&qca8075_3>; + label = "lan2"; +}; + +&dp4 { + status = "okay"; + phy-handle = <&qca8075_4>; + label = "lan1"; +}; + +&dp6_syn { + status = "okay"; + qcom,mactype = <1>; + phy-handle = <&aqr113c>; + label = "wan"; +}; + +&pcie_qmp0 { + status = "okay"; +}; + +&pcie0 { + status = "okay"; + + perst-gpio = <&tlmm 58 GPIO_ACTIVE_LOW>; + + bridge@0,0 { + reg = <0x00020000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; +}; + +&pcie_qmp1 { + status = "okay"; +}; + +&pcie1 { + status = "okay"; + + perst-gpio = <&tlmm 61 GPIO_ACTIVE_LOW>; + + bridge@1,0 { + reg = <0x00010000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + ranges; + + wifi@1,0 { + status = "okay"; + + /* ath11k has no DT compatible for PCI cards */ + compatible = "pci17cb,1104"; + reg = <0x00010000 0 0 0 0>; + + qcom,ath11k-calibration-variant = "prpl-Haze"; + }; + }; +}; + +&wifi { + status = "okay"; + + qcom,ath11k-calibration-variant = "prpl-Haze"; +}; diff --git a/target/linux/ipq807x/image/generic.mk b/target/linux/ipq807x/image/generic.mk index 1ea42845f01..6003f2a5c0e 100644 --- a/target/linux/ipq807x/image/generic.mk +++ b/target/linux/ipq807x/image/generic.mk @@ -14,7 +14,6 @@ define Device/EmmcImage IMAGES += factory.bin sysupgrade.bin IMAGE/factory.bin := append-rootfs | pad-rootfs | pad-to 64k IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-to 64k | sysupgrade-tar rootfs=$$$$@ | append-metadata - DEVICE_PACKAGES := e2fsprogs kmod-fs-ext4 losetup endef define Device/UbiFit @@ -108,6 +107,17 @@ define Device/netgear_wax218 endef TARGET_DEVICES += netgear_wax218 +define Device/prpl_haze + $(call Device/FitImage) + $(call Device/EmmcImage) + DEVICE_VENDOR := prpl Foundation + DEVICE_MODEL := Haze + DEVICE_DTS_CONFIG := config@hk09 + SOC := ipq8072 + DEVICE_PACKAGES += ath11k-firmware-qcn9074 ipq-wifi-prpl_haze kmod-ath11k-pci +endef +TARGET_DEVICES += prpl_haze + define Device/qnap_301w $(call Device/FitImage) $(call Device/EmmcImage) diff --git a/target/linux/lantiq/patches-5.15/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch b/target/linux/lantiq/patches-5.15/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch index f7fbfdf9e42..be0f0bfccd4 100644 --- a/target/linux/lantiq/patches-5.15/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch +++ b/target/linux/lantiq/patches-5.15/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch @@ -127,7 +127,7 @@ Signed-off-by: John Crispin + + if (!is_valid_ether_addr(athxk_eeprom_mac)) { + dev_warn(&pdev->dev, "using random mac\n"); -+ random_ether_addr(athxk_eeprom_mac); ++ eth_random_addr(athxk_eeprom_mac); + } + + if (!of_property_read_u32(np, "ath,mac-increment", &mac_inc)) diff --git a/target/linux/layerscape/patches-5.15/701-staging-add-fsl_ppfe-driver.patch b/target/linux/layerscape/patches-5.15/701-staging-add-fsl_ppfe-driver.patch index 9e602260838..6130bf0030f 100644 --- a/target/linux/layerscape/patches-5.15/701-staging-add-fsl_ppfe-driver.patch +++ b/target/linux/layerscape/patches-5.15/701-staging-add-fsl_ppfe-driver.patch @@ -7,7 +7,7 @@ Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is squash of all commits with ppfe driver taken from NXP 5.15 tree: -https://source.codeaurora.org/external/qoriq/qoriq-components/linux/log/drivers/staging/fsl_ppfe?h=lf-5.15.y +https://github.com/nxp-qoriq/linux/commits/lf-5.15.y/drivers/staging/fsl_ppfe List of original commits: diff --git a/target/linux/mpc85xx/patches-5.15/100-powerpc-85xx-tl-wdr4900-v1-support.patch b/target/linux/mpc85xx/patches-5.15/100-powerpc-85xx-tl-wdr4900-v1-support.patch index e1e817c1f20..0ecbec3ca41 100644 --- a/target/linux/mpc85xx/patches-5.15/100-powerpc-85xx-tl-wdr4900-v1-support.patch +++ b/target/linux/mpc85xx/patches-5.15/100-powerpc-85xx-tl-wdr4900-v1-support.patch @@ -38,7 +38,7 @@ Signed-off-by: Pawel Dembicki --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper -@@ -326,6 +326,11 @@ adder875-redboot) +@@ -339,6 +339,11 @@ adder875-redboot) platformo="$object/fixed-head.o $object/redboot-8xx.o" binary=y ;; diff --git a/target/linux/mpc85xx/patches-5.15/107-powerpc-85xx-add-ws-ap3825i-support.patch b/target/linux/mpc85xx/patches-5.15/107-powerpc-85xx-add-ws-ap3825i-support.patch index b211f3cb302..bd731a23445 100644 --- a/target/linux/mpc85xx/patches-5.15/107-powerpc-85xx-add-ws-ap3825i-support.patch +++ b/target/linux/mpc85xx/patches-5.15/107-powerpc-85xx-add-ws-ap3825i-support.patch @@ -55,7 +55,7 @@ WS-AP3825i AP. --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper -@@ -326,6 +326,7 @@ adder875-redboot) +@@ -339,6 +339,7 @@ adder875-redboot) platformo="$object/fixed-head.o $object/redboot-8xx.o" binary=y ;; diff --git a/target/linux/mpc85xx/patches-5.15/109-powerpc-85xx-add-ws-ap3715i-support.patch b/target/linux/mpc85xx/patches-5.15/109-powerpc-85xx-add-ws-ap3715i-support.patch index 8272d9dd2ae..692cef0417d 100644 --- a/target/linux/mpc85xx/patches-5.15/109-powerpc-85xx-add-ws-ap3715i-support.patch +++ b/target/linux/mpc85xx/patches-5.15/109-powerpc-85xx-add-ws-ap3715i-support.patch @@ -40,7 +40,7 @@ image-$(CONFIG_MVME7100) += dtbImage.mvme7100 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper -@@ -326,6 +326,7 @@ adder875-redboot) +@@ -339,6 +339,7 @@ adder875-redboot) platformo="$object/fixed-head.o $object/redboot-8xx.o" binary=y ;; diff --git a/target/linux/mpc85xx/patches-5.15/110-powerpc-85xx-br200-wp-support.patch b/target/linux/mpc85xx/patches-5.15/110-powerpc-85xx-br200-wp-support.patch index 8d510759dcf..eb70a4c4c47 100644 --- a/target/linux/mpc85xx/patches-5.15/110-powerpc-85xx-br200-wp-support.patch +++ b/target/linux/mpc85xx/patches-5.15/110-powerpc-85xx-br200-wp-support.patch @@ -47,7 +47,7 @@ image-$(CONFIG_WS_AP3825I) += simpleImage.ws-ap3825i --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper -@@ -326,6 +326,7 @@ adder875-redboot) +@@ -339,6 +339,7 @@ adder875-redboot) platformo="$object/fixed-head.o $object/redboot-8xx.o" binary=y ;; diff --git a/target/linux/ramips/dts/mt7621_beeline_smartbox-turbo-plus.dts b/target/linux/ramips/dts/mt7621_beeline_smartbox-turbo-plus.dts new file mode 100644 index 00000000000..507920bac22 --- /dev/null +++ b/target/linux/ramips/dts/mt7621_beeline_smartbox-turbo-plus.dts @@ -0,0 +1,248 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "mt7621.dtsi" + +#include +#include +#include + +/ { + compatible = "beeline,smartbox-turbo-plus", "mediatek,mt7621-soc"; + model = "Beeline SmartBox TURBO+"; + + aliases { + label-mac-device = &gmac0; + + led-boot = &led_status_green; + led-failsafe = &led_status_red; + led-running = &led_status_green; + led-upgrade = &led_status_red; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + label = "blue:wan"; + color = ; + function = LED_FUNCTION_WAN; + gpios = <&gpio 13 GPIO_ACTIVE_HIGH>; + }; + + led_status_green: led-1 { + label = "green:status"; + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&gpio 15 GPIO_ACTIVE_HIGH>; + }; + + led_status_red: led-2 { + label = "red:status"; + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&gpio 16 GPIO_ACTIVE_HIGH>; + }; + }; + + keys { + compatible = "gpio-keys"; + + wps { + label = "wps"; + gpios = <&gpio 11 GPIO_ACTIVE_HIGH>; + linux,code = ; + }; + + reset { + label = "reset"; + gpios = <&gpio 14 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + ubi-concat { + compatible = "mtd-concat"; + devices = <&ubiconcat0 &ubiconcat1 &ubiconcat2>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "ubi"; + reg = <0x0 0x4f80000>; + }; + }; + }; +}; + +&nand { + status = "okay"; + + partitions { + compatible = "sercomm,sc-partitions", "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x100000>; + sercomm,scpart-id = <0>; + read-only; + }; + + partition@100000 { + label = "dynamic partition map"; + reg = <0x100000 0x100000>; + sercomm,scpart-id = <1>; + read-only; + }; + + factory: partition@200000 { + label = "Factory"; + reg = <0x200000 0x100000>; + sercomm,scpart-id = <2>; + read-only; + + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_factory_21000: macaddr@21000 { + reg = <0x21000 0x6>; + }; + }; + + partition@300000 { + label = "Boot Flag"; + reg = <0x300000 0x100000>; + sercomm,scpart-id = <3>; + }; + + partition@400000 { + label = "kernel"; + reg = <0x400000 0x600000>; + sercomm,scpart-id = <4>; + }; + + partition@a00000 { + label = "Kernel 2"; + reg = <0xa00000 0x600000>; + sercomm,scpart-id = <5>; + read-only; + }; + + ubiconcat0: partition@1000000 { + label = "File System 1"; + reg = <0x1000000 0x2000000>; + sercomm,scpart-id = <6>; + }; + + partition@3000000 { + label = "File System 2"; + reg = <0x3000000 0x2000000>; + sercomm,scpart-id = <7>; + read-only; + }; + + ubiconcat1: partition@5000000 { + label = "Configuration/log"; + reg = <0x5000000 0x1400000>; + sercomm,scpart-id = <8>; + }; + + ubiconcat2: partition@6400000 { + label = "application tmp buffer (Ftool)"; + reg = <0x6400000 0x1b80000>; + sercomm,scpart-id = <9>; + }; + }; +}; + +&pcie { + status = "okay"; +}; + +&pcie0 { + wifi@0,0 { + compatible = "mediatek,mt76"; + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x8000>; + ieee80211-freq-limit = <5000000 6000000>; + + nvmem-cells = <&macaddr_factory_21000>; + nvmem-cell-names = "mac-address"; + mac-address-increment = <(5)>; + }; +}; + +&pcie1 { + wifi@0,0 { + compatible = "mediatek,mt76"; + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x0>; + ieee80211-freq-limit = <2400000 2500000>; + + nvmem-cells = <&macaddr_factory_21000>; + nvmem-cell-names = "mac-address"; + mac-address-increment = <(4)>; + }; +}; + +&gmac0 { + nvmem-cells = <&macaddr_factory_21000>; + nvmem-cell-names = "mac-address"; +}; + +&gmac1 { + status = "okay"; + label = "wan"; + phy-handle = <ðphy0>; + + nvmem-cells = <&macaddr_factory_21000>; + nvmem-cell-names = "mac-address"; + mac-address-increment = <(1)>; +}; + +&mdio { + ethphy0: ethernet-phy@0 { + reg = <0>; + }; +}; + +&switch0 { + ports { + port@1 { + status = "okay"; + label = "lan1"; + }; + + port@2 { + status = "okay"; + label = "lan2"; + }; + + port@3 { + status = "okay"; + label = "lan3"; + }; + + port@4 { + status = "okay"; + label = "lan4"; + }; + }; +}; + +&uartlite3 { + status = "okay"; + current-speed = <57600>; +}; + +&state_default { + gpio { + groups = "i2c", "jtag"; + function = "gpio"; + }; +}; diff --git a/target/linux/ramips/dts/mt7621_yuncore_fap640.dts b/target/linux/ramips/dts/mt7621_yuncore_fap640.dts index a0c32a02116..d525dde385b 100644 --- a/target/linux/ramips/dts/mt7621_yuncore_fap640.dts +++ b/target/linux/ramips/dts/mt7621_yuncore_fap640.dts @@ -148,10 +148,26 @@ }; &gmac0 { + nvmem-cells = <&macaddr_factory_e006>; + nvmem-cell-names = "mac-address"; +}; + +&gmac1 { + status = "okay"; + label = "wan"; + phy-handle = <ðphy4>; + nvmem-cells = <&macaddr_factory_0004>; nvmem-cell-names = "mac-address"; }; +&mdio { + ethphy4: ethernet-phy@4 { + reg = <4>; + }; +}; + + &switch0 { gpio-controller; #gpio-cells = <2>; @@ -176,13 +192,6 @@ status = "okay"; label = "lan1"; }; - - port@4 { - status = "okay"; - label = "wan"; - nvmem-cells = <&macaddr_factory_0004>; - nvmem-cell-names = "mac-address"; - }; }; }; @@ -201,5 +210,9 @@ macaddr_factory_0004: macaddr@0004 { reg = <0x0004 0x6>; }; + + macaddr_factory_e006: macaddr@e006 { + reg = <0xe006 0x6>; + }; }; diff --git a/target/linux/ramips/image/common-sercomm.mk b/target/linux/ramips/image/common-sercomm.mk index 83bb2a742c9..fbe29d70174 100644 --- a/target/linux/ramips/image/common-sercomm.mk +++ b/target/linux/ramips/image/common-sercomm.mk @@ -1,4 +1,5 @@ DEVICE_VARS += SERCOMM_KERNEL_OFFSET SERCOMM_ROOTFS_OFFSET +DEVICE_VARS += SERCOMM_KERNEL2_OFFSET SERCOMM_ROOTFS2_OFFSET define Build/sercomm-crypto $(TOPDIR)/scripts/sercomm-crypto.py \ @@ -16,6 +17,23 @@ define Build/sercomm-crypto rm -f $@.enc $@.key endef +define Build/sercomm-factory-cqr + $(TOPDIR)/scripts/sercomm-pid.py \ + --hw-version $(SERCOMM_HWVER) \ + --hw-id $(SERCOMM_HWID) \ + --sw-version $(SERCOMM_SWVER) \ + --pid-file $@.fhdr + printf $$(stat -c%s $(IMAGE_KERNEL)) | \ + dd seek=$$((0x70)) of=$@.fhdr bs=1 conv=notrunc 2>/dev/null + printf $$(($$(stat -c%s $@)-$$(stat -c%s $(IMAGE_KERNEL))-$$((0x200)))) | \ + dd seek=$$((0x80)) of=$@.fhdr bs=1 conv=notrunc 2>/dev/null + dd bs=$$((0x200)) skip=1 if=$@ conv=notrunc 2>/dev/null | \ + $(MKHASH) md5 | awk '{print $$1}' | tr -d '\n' | \ + dd seek=$$((0x1e0)) of=$@.fhdr bs=1 conv=notrunc 2>/dev/null + dd if=$@ >> $@.fhdr 2>/dev/null + mv $@.fhdr $@ +endef + define Build/sercomm-kernel $(TOPDIR)/scripts/sercomm-kernel-header.py \ --kernel-image $@ \ @@ -26,6 +44,22 @@ define Build/sercomm-kernel mv $@.hdr $@ endef +define Build/sercomm-kernel-factory + $(TOPDIR)/scripts/sercomm-kernel-header.py \ + --kernel-image $@ \ + --kernel-offset $(SERCOMM_KERNEL_OFFSET) \ + --rootfs-offset $(SERCOMM_ROOTFS_OFFSET) \ + --output-header $@.khdr1 + $(TOPDIR)/scripts/sercomm-kernel-header.py \ + --kernel-image $@ \ + --kernel-offset $(SERCOMM_KERNEL2_OFFSET) \ + --rootfs-offset $(SERCOMM_ROOTFS2_OFFSET) \ + --output-header $@.khdr2 + cat $@.khdr1 $@.khdr2 > $@.khdr + dd if=$@ >> $@.khdr 2>/dev/null + mv $@.khdr $@ +endef + define Build/sercomm-part-tag $(call Build/sercomm-part-tag-common,$(word 1,$(1)) $@) endef @@ -64,24 +98,37 @@ define Build/sercomm-prepend-tagged-kernel mv $(IMAGE_KERNEL).tagged $@ endef -define Device/sercomm_dxx - $(Device/dsa-migration) - BLOCKSIZE := 128k - PAGESIZE := 2048 - KERNEL_SIZE := 6144k - UBINIZE_OPTS := -E 5 +define Device/sercomm + $(Device/nand) LOADER_TYPE := bin + KERNEL_SIZE := 6144k KERNEL_LOADADDR := 0x81001000 LZMA_TEXT_START := 0x82800000 + SERCOMM_KERNEL_OFFSET := 0x400100 + SERCOMM_ROOTFS_OFFSET := 0x1000000 + IMAGES += factory.img +endef + +define Device/sercomm_cxx + $(Device/sercomm) + SERCOMM_KERNEL2_OFFSET := 0xa00100 + SERCOMM_ROOTFS2_OFFSET := 0x3000000 + KERNEL := kernel-bin | append-dtb | lzma | loader-kernel | lzma -a0 | \ + uImage lzma + IMAGE/sysupgrade.bin := append-kernel | sercomm-kernel | \ + sysupgrade-tar kernel=$$$$@ | append-metadata + IMAGE/factory.img := append-kernel | sercomm-kernel-factory | \ + append-ubi | sercomm-factory-cqr +endef + +define Device/sercomm_dxx + $(Device/sercomm) KERNEL := kernel-bin | append-dtb | lzma | loader-kernel | lzma -a0 | \ uImage lzma | sercomm-kernel KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | loader-kernel | \ lzma -a0 | uImage lzma - IMAGES += factory.img IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata IMAGE/factory.img := append-ubi | check-size | \ sercomm-part-tag rootfs | sercomm-prepend-tagged-kernel kernel | \ gzip | sercomm-payload | sercomm-crypto - SERCOMM_KERNEL_OFFSET := 0x400100 - SERCOMM_ROOTFS_OFFSET := 0x1000000 endef diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk index 340d4ba4a1b..b8fa0cefdb3 100644 --- a/target/linux/ramips/image/mt7621.mk +++ b/target/linux/ramips/image/mt7621.mk @@ -410,6 +410,18 @@ define Device/beeline_smartbox-turbo endef TARGET_DEVICES += beeline_smartbox-turbo +define Device/beeline_smartbox-turbo-plus + $(Device/sercomm_cxx) + IMAGE_SIZE := 32768k + SERCOMM_HWID := CQR + SERCOMM_HWVER := 10000 + SERCOMM_SWVER := 2010 + DEVICE_VENDOR := Beeline + DEVICE_MODEL := SmartBox TURBO+ + DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615-firmware kmod-usb3 +endef +TARGET_DEVICES += beeline_smartbox-turbo-plus + define Device/belkin_rt1800 $(Device/nand) IMAGE_SIZE := 49152k diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds b/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds index b243acbbbf4..9b15da0d22b 100644 --- a/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds +++ b/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds @@ -35,6 +35,7 @@ asus,rt-n56u-b1) beeline,smartbox-flash|\ beeline,smartbox-giga|\ beeline,smartbox-turbo|\ +beeline,smartbox-turbo-plus|\ etisalat,s3|\ rostelecom,rt-sf-1) ucidef_set_led_netdev "wan" "wan" "blue:wan" "wan" diff --git a/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount b/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount index 597c2da60fb..9db700bff55 100755 --- a/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount +++ b/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount @@ -9,6 +9,7 @@ boot() { echo -e "bootcount\nbootchanged\n" | /usr/sbin/fw_setenv -s - ;; beeline,smartbox-turbo|\ + beeline,smartbox-turbo-plus|\ rostelecom,rt-sf-1) [[ $(hexdump -n 1 -e '/1 "%1d"' -s $((0x20001)) /dev/mtd3) == \ $((0xff)) ]] || printf '\xff' | dd of=/dev/mtdblock3 \ diff --git a/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh b/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh index ce5fdd61ed0..cef58ec3bad 100755 --- a/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh +++ b/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh @@ -60,6 +60,7 @@ platform_do_upgrade() { beeline,smartbox-flash|\ beeline,smartbox-giga|\ beeline,smartbox-turbo|\ + beeline,smartbox-turbo-plus|\ belkin,rt1800|\ dlink,dap-x1860-a1|\ dlink,dir-1960-a1|\ diff --git a/target/linux/ramips/patches-5.15/810-uvc-add-iPassion-iP2970-support.patch b/target/linux/ramips/patches-5.15/810-uvc-add-iPassion-iP2970-support.patch index 2d56440610e..88809ae68d0 100644 --- a/target/linux/ramips/patches-5.15/810-uvc-add-iPassion-iP2970-support.patch +++ b/target/linux/ramips/patches-5.15/810-uvc-add-iPassion-iP2970-support.patch @@ -13,7 +13,7 @@ Signed-off-by: John Crispin --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c -@@ -3152,6 +3152,18 @@ static const struct usb_device_id uvc_id +@@ -3158,6 +3158,18 @@ static const struct usb_device_id uvc_id .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, diff --git a/toolchain/gcc/patches-11.x/700-RISCV-Inline-subword-atomic-ops.patch b/toolchain/gcc/patches-11.x/700-RISCV-Inline-subword-atomic-ops.patch new file mode 100644 index 00000000000..0da7eb4af66 --- /dev/null +++ b/toolchain/gcc/patches-11.x/700-RISCV-Inline-subword-atomic-ops.patch @@ -0,0 +1,2021 @@ +From f797260adaf52bee0ec0e16190bbefbe1bfc3692 Mon Sep 17 00:00:00 2001 +From: Patrick O'Neill +Date: Tue, 18 Apr 2023 14:33:13 -0700 +Subject: [PATCH] RISCV: Inline subword atomic ops + +RISC-V has no support for subword atomic operations; code currently +generates libatomic library calls. + +This patch changes the default behavior to inline subword atomic calls +(using the same logic as the existing library call). +Behavior can be specified using the -minline-atomics and +-mno-inline-atomics command line flags. + +gcc/libgcc/config/riscv/atomic.c has the same logic implemented in asm. +This will need to stay for backwards compatibility and the +-mno-inline-atomics flag. + +2023-04-18 Patrick O'Neill + +gcc/ChangeLog: + PR target/104338 + * config/riscv/riscv-protos.h: Add helper function stubs. + * config/riscv/riscv.cc: Add helper functions for subword masking. + * config/riscv/riscv.opt: Add command-line flag. + * config/riscv/sync.md: Add masking logic and inline asm for fetch_and_op, + fetch_and_nand, CAS, and exchange ops. + * doc/invoke.texi: Add blurb regarding command-line flag. + +libgcc/ChangeLog: + PR target/104338 + * config/riscv/atomic.c: Add reference to duplicate logic. + +gcc/testsuite/ChangeLog: + PR target/104338 + * gcc.target/riscv/inline-atomics-1.c: New test. + * gcc.target/riscv/inline-atomics-2.c: New test. + * gcc.target/riscv/inline-atomics-3.c: New test. + * gcc.target/riscv/inline-atomics-4.c: New test. + * gcc.target/riscv/inline-atomics-5.c: New test. + * gcc.target/riscv/inline-atomics-6.c: New test. + * gcc.target/riscv/inline-atomics-7.c: New test. + * gcc.target/riscv/inline-atomics-8.c: New test. + +Signed-off-by: Patrick O'Neill +Signed-off-by: Palmer Dabbelt +--- + gcc/config/riscv/riscv-protos.h | 2 + + gcc/config/riscv/riscv.cc | 49 ++ + gcc/config/riscv/riscv.opt | 4 + + gcc/config/riscv/sync.md | 301 +++++++++ + gcc/doc/invoke.texi | 10 +- + .../gcc.target/riscv/inline-atomics-1.c | 18 + + .../gcc.target/riscv/inline-atomics-2.c | 9 + + .../gcc.target/riscv/inline-atomics-3.c | 569 ++++++++++++++++++ + .../gcc.target/riscv/inline-atomics-4.c | 566 +++++++++++++++++ + .../gcc.target/riscv/inline-atomics-5.c | 87 +++ + .../gcc.target/riscv/inline-atomics-6.c | 87 +++ + .../gcc.target/riscv/inline-atomics-7.c | 69 +++ + .../gcc.target/riscv/inline-atomics-8.c | 69 +++ + libgcc/config/riscv/atomic.c | 2 + + 14 files changed, 1841 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-1.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-2.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-3.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-4.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-5.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-6.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-7.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-8.c + +--- a/gcc/config/riscv/riscv-protos.h ++++ b/gcc/config/riscv/riscv-protos.h +@@ -74,6 +74,8 @@ extern bool riscv_expand_block_move (rtx + extern bool riscv_store_data_bypass_p (rtx_insn *, rtx_insn *); + extern rtx riscv_gen_gpr_save_insn (struct riscv_frame_info *); + extern bool riscv_gpr_save_operation_p (rtx); ++extern void riscv_subword_address (rtx, rtx *, rtx *, rtx *, rtx *); ++extern void riscv_lshift_subword (machine_mode, rtx, rtx, rtx *); + + /* Routines implemented in riscv-c.c. */ + void riscv_cpu_cpp_builtins (cpp_reader *); +--- a/gcc/config/riscv/riscv.c ++++ b/gcc/config/riscv/riscv.c +@@ -5351,6 +5351,55 @@ riscv_asan_shadow_offset (void) + return TARGET_64BIT ? (HOST_WIDE_INT_1 << 29) : 0; + } + ++/* Given memory reference MEM, expand code to compute the aligned ++ memory address, shift and mask values and store them into ++ *ALIGNED_MEM, *SHIFT, *MASK and *NOT_MASK. */ ++ ++void ++riscv_subword_address (rtx mem, rtx *aligned_mem, rtx *shift, rtx *mask, ++ rtx *not_mask) ++{ ++ /* Align the memory address to a word. */ ++ rtx addr = force_reg (Pmode, XEXP (mem, 0)); ++ ++ rtx addr_mask = gen_int_mode (-4, Pmode); ++ ++ rtx aligned_addr = gen_reg_rtx (Pmode); ++ emit_move_insn (aligned_addr, gen_rtx_AND (Pmode, addr, addr_mask)); ++ ++ *aligned_mem = change_address (mem, SImode, aligned_addr); ++ ++ /* Calculate the shift amount. */ ++ emit_move_insn (*shift, gen_rtx_AND (SImode, gen_lowpart (SImode, addr), ++ gen_int_mode (3, SImode))); ++ emit_move_insn (*shift, gen_rtx_ASHIFT (SImode, *shift, ++ gen_int_mode (3, SImode))); ++ ++ /* Calculate the mask. */ ++ int unshifted_mask = GET_MODE_MASK (GET_MODE (mem)); ++ ++ emit_move_insn (*mask, gen_int_mode (unshifted_mask, SImode)); ++ ++ emit_move_insn (*mask, gen_rtx_ASHIFT (SImode, *mask, ++ gen_lowpart (QImode, *shift))); ++ ++ emit_move_insn (*not_mask, gen_rtx_NOT(SImode, *mask)); ++} ++ ++/* Leftshift a subword within an SImode register. */ ++ ++void ++riscv_lshift_subword (machine_mode mode, rtx value, rtx shift, ++ rtx *shifted_value) ++{ ++ rtx value_reg = gen_reg_rtx (SImode); ++ emit_move_insn (value_reg, simplify_gen_subreg (SImode, value, ++ mode, 0)); ++ ++ emit_move_insn(*shifted_value, gen_rtx_ASHIFT (SImode, value_reg, ++ gen_lowpart (QImode, shift))); ++} ++ + /* Initialize the GCC target structure. */ + #undef TARGET_ASM_ALIGNED_HI_OP + #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" +--- a/gcc/config/riscv/riscv.opt ++++ b/gcc/config/riscv/riscv.opt +@@ -195,6 +195,10 @@ long riscv_stack_protector_guard_offset + TargetVariable + int riscv_zi_subext + ++minline-atomics ++Target Var(TARGET_INLINE_SUBWORD_ATOMIC) Init(1) ++Always inline subword atomic operations. ++ + Enum + Name(isa_spec_class) Type(enum riscv_isa_spec_class) + Supported ISA specs (for use with the -misa-spec= option): +--- a/gcc/config/riscv/sync.md ++++ b/gcc/config/riscv/sync.md +@@ -21,8 +21,11 @@ + + (define_c_enum "unspec" [ + UNSPEC_COMPARE_AND_SWAP ++ UNSPEC_COMPARE_AND_SWAP_SUBWORD + UNSPEC_SYNC_OLD_OP ++ UNSPEC_SYNC_OLD_OP_SUBWORD + UNSPEC_SYNC_EXCHANGE ++ UNSPEC_SYNC_EXCHANGE_SUBWORD + UNSPEC_ATOMIC_STORE + UNSPEC_MEMORY_BARRIER + ]) +@@ -92,6 +95,135 @@ + "%F3amo.%A3 %0,%z2,%1" + [(set (attr "length") (const_int 8))]) + ++(define_insn "subword_atomic_fetch_strong_" ++ [(set (match_operand:SI 0 "register_operand" "=&r") ;; old value at mem ++ (match_operand:SI 1 "memory_operand" "+A")) ;; mem location ++ (set (match_dup 1) ++ (unspec_volatile:SI ++ [(any_atomic:SI (match_dup 1) ++ (match_operand:SI 2 "register_operand" "rI")) ;; value for op ++ (match_operand:SI 3 "register_operand" "rI")] ;; mask ++ UNSPEC_SYNC_OLD_OP_SUBWORD)) ++ (match_operand:SI 4 "register_operand" "rI") ;; not_mask ++ (clobber (match_scratch:SI 5 "=&r")) ;; tmp_1 ++ (clobber (match_scratch:SI 6 "=&r"))] ;; tmp_2 ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++ { ++ return "1:\;" ++ "lr.w.aq\t%0, %1\;" ++ "\t%5, %0, %2\;" ++ "and\t%5, %5, %3\;" ++ "and\t%6, %0, %4\;" ++ "or\t%6, %6, %5\;" ++ "sc.w.rl\t%5, %6, %1\;" ++ "bnez\t%5, 1b"; ++ } ++ [(set (attr "length") (const_int 28))]) ++ ++(define_expand "atomic_fetch_nand" ++ [(match_operand:SHORT 0 "register_operand") ;; old value at mem ++ (not:SHORT (and:SHORT (match_operand:SHORT 1 "memory_operand") ;; mem location ++ (match_operand:SHORT 2 "reg_or_0_operand"))) ;; value for op ++ (match_operand:SI 3 "const_int_operand")] ;; model ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ /* We have no QImode/HImode atomics, so form a mask, then use ++ subword_atomic_fetch_strong_nand to implement a LR/SC version of the ++ operation. */ ++ ++ /* Logic duplicated in gcc/libgcc/config/riscv/atomic.c for use when inlining ++ is disabled */ ++ ++ rtx old = gen_reg_rtx (SImode); ++ rtx mem = operands[1]; ++ rtx value = operands[2]; ++ rtx aligned_mem = gen_reg_rtx (SImode); ++ rtx shift = gen_reg_rtx (SImode); ++ rtx mask = gen_reg_rtx (SImode); ++ rtx not_mask = gen_reg_rtx (SImode); ++ ++ riscv_subword_address (mem, &aligned_mem, &shift, &mask, ¬_mask); ++ ++ rtx shifted_value = gen_reg_rtx (SImode); ++ riscv_lshift_subword (mode, value, shift, &shifted_value); ++ ++ emit_insn (gen_subword_atomic_fetch_strong_nand (old, aligned_mem, ++ shifted_value, ++ mask, not_mask)); ++ ++ emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old, ++ gen_lowpart (QImode, shift))); ++ ++ emit_move_insn (operands[0], gen_lowpart (mode, old)); ++ ++ DONE; ++}) ++ ++(define_insn "subword_atomic_fetch_strong_nand" ++ [(set (match_operand:SI 0 "register_operand" "=&r") ;; old value at mem ++ (match_operand:SI 1 "memory_operand" "+A")) ;; mem location ++ (set (match_dup 1) ++ (unspec_volatile:SI ++ [(not:SI (and:SI (match_dup 1) ++ (match_operand:SI 2 "register_operand" "rI"))) ;; value for op ++ (match_operand:SI 3 "register_operand" "rI")] ;; mask ++ UNSPEC_SYNC_OLD_OP_SUBWORD)) ++ (match_operand:SI 4 "register_operand" "rI") ;; not_mask ++ (clobber (match_scratch:SI 5 "=&r")) ;; tmp_1 ++ (clobber (match_scratch:SI 6 "=&r"))] ;; tmp_2 ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++ { ++ return "1:\;" ++ "lr.w.aq\t%0, %1\;" ++ "and\t%5, %0, %2\;" ++ "not\t%5, %5\;" ++ "and\t%5, %5, %3\;" ++ "and\t%6, %0, %4\;" ++ "or\t%6, %6, %5\;" ++ "sc.w.rl\t%5, %6, %1\;" ++ "bnez\t%5, 1b"; ++ } ++ [(set (attr "length") (const_int 32))]) ++ ++(define_expand "atomic_fetch_" ++ [(match_operand:SHORT 0 "register_operand") ;; old value at mem ++ (any_atomic:SHORT (match_operand:SHORT 1 "memory_operand") ;; mem location ++ (match_operand:SHORT 2 "reg_or_0_operand")) ;; value for op ++ (match_operand:SI 3 "const_int_operand")] ;; model ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ /* We have no QImode/HImode atomics, so form a mask, then use ++ subword_atomic_fetch_strong_ to implement a LR/SC version of the ++ operation. */ ++ ++ /* Logic duplicated in gcc/libgcc/config/riscv/atomic.c for use when inlining ++ is disabled */ ++ ++ rtx old = gen_reg_rtx (SImode); ++ rtx mem = operands[1]; ++ rtx value = operands[2]; ++ rtx aligned_mem = gen_reg_rtx (SImode); ++ rtx shift = gen_reg_rtx (SImode); ++ rtx mask = gen_reg_rtx (SImode); ++ rtx not_mask = gen_reg_rtx (SImode); ++ ++ riscv_subword_address (mem, &aligned_mem, &shift, &mask, ¬_mask); ++ ++ rtx shifted_value = gen_reg_rtx (SImode); ++ riscv_lshift_subword (mode, value, shift, &shifted_value); ++ ++ emit_insn (gen_subword_atomic_fetch_strong_ (old, aligned_mem, ++ shifted_value, ++ mask, not_mask)); ++ ++ emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old, ++ gen_lowpart (QImode, shift))); ++ ++ emit_move_insn (operands[0], gen_lowpart (mode, old)); ++ ++ DONE; ++}) ++ + (define_insn "atomic_exchange" + [(set (match_operand:GPR 0 "register_operand" "=&r") + (unspec_volatile:GPR +@@ -104,6 +236,56 @@ + "%F3amoswap.%A3 %0,%z2,%1" + [(set (attr "length") (const_int 8))]) + ++(define_expand "atomic_exchange" ++ [(match_operand:SHORT 0 "register_operand") ;; old value at mem ++ (match_operand:SHORT 1 "memory_operand") ;; mem location ++ (match_operand:SHORT 2 "register_operand") ;; value ++ (match_operand:SI 3 "const_int_operand")] ;; model ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ rtx old = gen_reg_rtx (SImode); ++ rtx mem = operands[1]; ++ rtx value = operands[2]; ++ rtx aligned_mem = gen_reg_rtx (SImode); ++ rtx shift = gen_reg_rtx (SImode); ++ rtx mask = gen_reg_rtx (SImode); ++ rtx not_mask = gen_reg_rtx (SImode); ++ ++ riscv_subword_address (mem, &aligned_mem, &shift, &mask, ¬_mask); ++ ++ rtx shifted_value = gen_reg_rtx (SImode); ++ riscv_lshift_subword (mode, value, shift, &shifted_value); ++ ++ emit_insn (gen_subword_atomic_exchange_strong (old, aligned_mem, ++ shifted_value, not_mask)); ++ ++ emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old, ++ gen_lowpart (QImode, shift))); ++ ++ emit_move_insn (operands[0], gen_lowpart (mode, old)); ++ DONE; ++}) ++ ++(define_insn "subword_atomic_exchange_strong" ++ [(set (match_operand:SI 0 "register_operand" "=&r") ;; old value at mem ++ (match_operand:SI 1 "memory_operand" "+A")) ;; mem location ++ (set (match_dup 1) ++ (unspec_volatile:SI ++ [(match_operand:SI 2 "reg_or_0_operand" "rI") ;; value ++ (match_operand:SI 3 "reg_or_0_operand" "rI")] ;; not_mask ++ UNSPEC_SYNC_EXCHANGE_SUBWORD)) ++ (clobber (match_scratch:SI 4 "=&r"))] ;; tmp_1 ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++ { ++ return "1:\;" ++ "lr.w.aq\t%0, %1\;" ++ "and\t%4, %0, %3\;" ++ "or\t%4, %4, %2\;" ++ "sc.w.rl\t%4, %4, %1\;" ++ "bnez\t%4, 1b"; ++ } ++ [(set (attr "length") (const_int 20))]) ++ + (define_insn "atomic_cas_value_strong" + [(set (match_operand:GPR 0 "register_operand" "=&r") + (match_operand:GPR 1 "memory_operand" "+A")) +@@ -152,6 +334,125 @@ + DONE; + }) + ++(define_expand "atomic_compare_and_swap" ++ [(match_operand:SI 0 "register_operand") ;; bool output ++ (match_operand:SHORT 1 "register_operand") ;; val output ++ (match_operand:SHORT 2 "memory_operand") ;; memory ++ (match_operand:SHORT 3 "reg_or_0_operand") ;; expected value ++ (match_operand:SHORT 4 "reg_or_0_operand") ;; desired value ++ (match_operand:SI 5 "const_int_operand") ;; is_weak ++ (match_operand:SI 6 "const_int_operand") ;; mod_s ++ (match_operand:SI 7 "const_int_operand")] ;; mod_f ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ emit_insn (gen_atomic_cas_value_strong (operands[1], operands[2], ++ operands[3], operands[4], ++ operands[6], operands[7])); ++ ++ rtx val = gen_reg_rtx (SImode); ++ if (operands[1] != const0_rtx) ++ emit_move_insn (val, gen_rtx_SIGN_EXTEND (SImode, operands[1])); ++ else ++ emit_move_insn (val, const0_rtx); ++ ++ rtx exp = gen_reg_rtx (SImode); ++ if (operands[3] != const0_rtx) ++ emit_move_insn (exp, gen_rtx_SIGN_EXTEND (SImode, operands[3])); ++ else ++ emit_move_insn (exp, const0_rtx); ++ ++ rtx compare = val; ++ if (exp != const0_rtx) ++ { ++ rtx difference = gen_rtx_MINUS (SImode, val, exp); ++ compare = gen_reg_rtx (SImode); ++ emit_move_insn (compare, difference); ++ } ++ ++ if (word_mode != SImode) ++ { ++ rtx reg = gen_reg_rtx (word_mode); ++ emit_move_insn (reg, gen_rtx_SIGN_EXTEND (word_mode, compare)); ++ compare = reg; ++ } ++ ++ emit_move_insn (operands[0], gen_rtx_EQ (SImode, compare, const0_rtx)); ++ DONE; ++}) ++ ++(define_expand "atomic_cas_value_strong" ++ [(match_operand:SHORT 0 "register_operand") ;; val output ++ (match_operand:SHORT 1 "memory_operand") ;; memory ++ (match_operand:SHORT 2 "reg_or_0_operand") ;; expected value ++ (match_operand:SHORT 3 "reg_or_0_operand") ;; desired value ++ (match_operand:SI 4 "const_int_operand") ;; mod_s ++ (match_operand:SI 5 "const_int_operand") ;; mod_f ++ (match_scratch:SHORT 6)] ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ /* We have no QImode/HImode atomics, so form a mask, then use ++ subword_atomic_cas_strong to implement a LR/SC version of the ++ operation. */ ++ ++ /* Logic duplicated in gcc/libgcc/config/riscv/atomic.c for use when inlining ++ is disabled */ ++ ++ rtx old = gen_reg_rtx (SImode); ++ rtx mem = operands[1]; ++ rtx aligned_mem = gen_reg_rtx (SImode); ++ rtx shift = gen_reg_rtx (SImode); ++ rtx mask = gen_reg_rtx (SImode); ++ rtx not_mask = gen_reg_rtx (SImode); ++ ++ riscv_subword_address (mem, &aligned_mem, &shift, &mask, ¬_mask); ++ ++ rtx o = operands[2]; ++ rtx n = operands[3]; ++ rtx shifted_o = gen_reg_rtx (SImode); ++ rtx shifted_n = gen_reg_rtx (SImode); ++ ++ riscv_lshift_subword (mode, o, shift, &shifted_o); ++ riscv_lshift_subword (mode, n, shift, &shifted_n); ++ ++ emit_move_insn (shifted_o, gen_rtx_AND (SImode, shifted_o, mask)); ++ emit_move_insn (shifted_n, gen_rtx_AND (SImode, shifted_n, mask)); ++ ++ emit_insn (gen_subword_atomic_cas_strong (old, aligned_mem, ++ shifted_o, shifted_n, ++ mask, not_mask)); ++ ++ emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old, ++ gen_lowpart (QImode, shift))); ++ ++ emit_move_insn (operands[0], gen_lowpart (mode, old)); ++ ++ DONE; ++}) ++ ++(define_insn "subword_atomic_cas_strong" ++ [(set (match_operand:SI 0 "register_operand" "=&r") ;; old value at mem ++ (match_operand:SI 1 "memory_operand" "+A")) ;; mem location ++ (set (match_dup 1) ++ (unspec_volatile:SI [(match_operand:SI 2 "reg_or_0_operand" "rJ") ;; expected value ++ (match_operand:SI 3 "reg_or_0_operand" "rJ")] ;; desired value ++ UNSPEC_COMPARE_AND_SWAP_SUBWORD)) ++ (match_operand:SI 4 "register_operand" "rI") ;; mask ++ (match_operand:SI 5 "register_operand" "rI") ;; not_mask ++ (clobber (match_scratch:SI 6 "=&r"))] ;; tmp_1 ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++ { ++ return "1:\;" ++ "lr.w.aq\t%0, %1\;" ++ "and\t%6, %0, %4\;" ++ "bne\t%6, %z2, 1f\;" ++ "and\t%6, %0, %5\;" ++ "or\t%6, %6, %3\;" ++ "sc.w.rl\t%6, %6, %1\;" ++ "bnez\t%6, 1b\;" ++ "1:"; ++ } ++ [(set (attr "length") (const_int 28))]) ++ + (define_expand "atomic_test_and_set" + [(match_operand:QI 0 "register_operand" "") ;; bool output + (match_operand:QI 1 "memory_operand" "+A") ;; memory +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -734,7 +734,8 @@ Objective-C and Objective-C++ Dialects}. + -moverride=@var{string} -mverbose-cost-dump @gol + -mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{sysreg} @gol + -mstack-protector-guard-offset=@var{offset} -mtrack-speculation @gol +--moutline-atomics } ++-moutline-atomics ++-minline-atomics -mno-inline-atomics} + + @emph{Adapteva Epiphany Options} + @gccoptlist{-mhalf-reg-file -mprefer-short-insn-regs @gol +@@ -26742,6 +26743,13 @@ Do or don't use smaller but slower prolo + library function calls. The default is to use fast inline prologues and + epilogues. + ++@opindex minline-atomics ++@item -minline-atomics ++@itemx -mno-inline-atomics ++Do or don't use smaller but slower subword atomic emulation code that uses ++libatomic function calls. The default is to use fast inline subword atomics ++that do not require libatomic. ++ + @item -mshorten-memrefs + @itemx -mno-shorten-memrefs + @opindex mshorten-memrefs +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-1.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mno-inline-atomics" } */ ++/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "fetch_and_nand" { target *-*-* } 0 } */ ++/* { dg-final { scan-assembler "\tcall\t__sync_fetch_and_add_1" } } */ ++/* { dg-final { scan-assembler "\tcall\t__sync_fetch_and_nand_1" } } */ ++/* { dg-final { scan-assembler "\tcall\t__sync_bool_compare_and_swap_1" } } */ ++ ++char foo; ++char bar; ++char baz; ++ ++int ++main () ++{ ++ __sync_fetch_and_add(&foo, 1); ++ __sync_fetch_and_nand(&bar, 1); ++ __sync_bool_compare_and_swap (&baz, 1, 2); ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-2.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile } */ ++/* Verify that subword atomics do not generate calls. */ ++/* { dg-options "-minline-atomics" } */ ++/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "fetch_and_nand" { target *-*-* } 0 } */ ++/* { dg-final { scan-assembler-not "\tcall\t__sync_fetch_and_add_1" } } */ ++/* { dg-final { scan-assembler-not "\tcall\t__sync_fetch_and_nand_1" } } */ ++/* { dg-final { scan-assembler-not "\tcall\t__sync_bool_compare_and_swap_1" } } */ ++ ++#include "inline-atomics-1.c" +\ No newline at end of file +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-3.c +@@ -0,0 +1,569 @@ ++/* Check all char alignments. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-op-1.c */ ++/* Test __atomic routines for existence and proper execution on 1 byte ++ values with each valid memory model. */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics -Wno-address-of-packed-member" } */ ++ ++/* Test the execution of the __atomic_*OP builtin routines for a char. */ ++ ++extern void abort(void); ++ ++char count, res; ++const char init = ~0; ++ ++struct A ++{ ++ char a; ++ char b; ++ char c; ++ char d; ++} __attribute__ ((packed)) A; ++ ++/* The fetch_op routines return the original value before the operation. */ ++ ++void ++test_fetch_add (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_CONSUME) != 1) ++ abort (); ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_ACQUIRE) != 2) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_RELEASE) != 3) ++ abort (); ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_ACQ_REL) != 4) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_SEQ_CST) != 5) ++ abort (); ++} ++ ++ ++void ++test_fetch_sub (char* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_RELAXED) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_CONSUME) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQUIRE) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_RELEASE) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQ_REL) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_SEQ_CST) != res--) ++ abort (); ++} ++ ++void ++test_fetch_and (char* v) ++{ ++ *v = init; ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, init, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_fetch_and (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_fetch_nand (char* v) ++{ ++ *v = init; ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_ACQUIRE) != 0 ) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL) != 0) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++void ++test_fetch_xor (char* v) ++{ ++ *v = init; ++ count = 0; ++ ++ if (__atomic_fetch_xor (v, count, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE) != 0) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++void ++test_fetch_or (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_fetch_or (v, count, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, 2, __ATOMIC_CONSUME) != 1) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_ACQUIRE) != 3) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, 8, __ATOMIC_RELEASE) != 7) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_ACQ_REL) != 15) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_SEQ_CST) != 31) ++ abort (); ++} ++ ++/* The OP_fetch routines return the new value after the operation. */ ++ ++void ++test_add_fetch (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_RELAXED) != 1) ++ abort (); ++ ++ if (__atomic_add_fetch (v, 1, __ATOMIC_CONSUME) != 2) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_ACQUIRE) != 3) ++ abort (); ++ ++ if (__atomic_add_fetch (v, 1, __ATOMIC_RELEASE) != 4) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_ACQ_REL) != 5) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_SEQ_CST) != 6) ++ abort (); ++} ++ ++ ++void ++test_sub_fetch (char* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, 1, __ATOMIC_CONSUME) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQUIRE) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, 1, __ATOMIC_RELEASE) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_SEQ_CST) != --res) ++ abort (); ++} ++ ++void ++test_and_fetch (char* v) ++{ ++ *v = init; ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ *v = init; ++ if (__atomic_and_fetch (v, init, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_and_fetch (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_and_fetch (v, 0, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_nand_fetch (char* v) ++{ ++ *v = init; ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_RELEASE) != 0) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++ ++ ++void ++test_xor_fetch (char* v) ++{ ++ *v = init; ++ count = 0; ++ ++ if (__atomic_xor_fetch (v, count, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_or_fetch (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_or_fetch (v, count, __ATOMIC_RELAXED) != 1) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, 2, __ATOMIC_CONSUME) != 3) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_ACQUIRE) != 7) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, 8, __ATOMIC_RELEASE) != 15) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_ACQ_REL) != 31) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_SEQ_CST) != 63) ++ abort (); ++} ++ ++ ++/* Test the OP routines with a result which isn't used. Use both variations ++ within each function. */ ++ ++void ++test_add (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ __atomic_add_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != 1) ++ abort (); ++ ++ __atomic_fetch_add (v, count, __ATOMIC_CONSUME); ++ if (*v != 2) ++ abort (); ++ ++ __atomic_add_fetch (v, 1 , __ATOMIC_ACQUIRE); ++ if (*v != 3) ++ abort (); ++ ++ __atomic_fetch_add (v, 1, __ATOMIC_RELEASE); ++ if (*v != 4) ++ abort (); ++ ++ __atomic_add_fetch (v, count, __ATOMIC_ACQ_REL); ++ if (*v != 5) ++ abort (); ++ ++ __atomic_fetch_add (v, count, __ATOMIC_SEQ_CST); ++ if (*v != 6) ++ abort (); ++} ++ ++ ++void ++test_sub (char* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ __atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, count + 1, __ATOMIC_CONSUME); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_sub_fetch (v, 1, __ATOMIC_ACQUIRE); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, 1, __ATOMIC_RELEASE); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, count + 1, __ATOMIC_SEQ_CST); ++ if (*v != --res) ++ abort (); ++} ++ ++void ++test_and (char* v) ++{ ++ *v = init; ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_RELAXED); ++ if (*v != 0) ++ abort (); ++ ++ *v = init; ++ __atomic_fetch_and (v, init, __ATOMIC_CONSUME); ++ if (*v != init) ++ abort (); ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != 0) ++ abort (); ++ ++ *v = ~*v; ++ __atomic_fetch_and (v, init, __ATOMIC_RELEASE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL); ++ if (*v != 0) ++ abort (); ++ ++ *v = ~*v; ++ __atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST); ++ if (*v != 0) ++ abort (); ++} ++ ++void ++test_nand (char* v) ++{ ++ *v = init; ++ ++ __atomic_fetch_nand (v, 0, __ATOMIC_RELAXED); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_nand (v, init, __ATOMIC_CONSUME); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_nand_fetch (v, init, __ATOMIC_RELEASE); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL); ++ if (*v != init) ++ abort (); ++ ++ __atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST); ++ if (*v != init) ++ abort (); ++} ++ ++ ++ ++void ++test_xor (char* v) ++{ ++ *v = init; ++ count = 0; ++ ++ __atomic_xor_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL); ++ if (*v != init) ++ abort (); ++ ++ __atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST); ++ if (*v != 0) ++ abort (); ++} ++ ++void ++test_or (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ __atomic_or_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != 1) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, count, __ATOMIC_CONSUME); ++ if (*v != 3) ++ abort (); ++ ++ count *= 2; ++ __atomic_or_fetch (v, 4, __ATOMIC_ACQUIRE); ++ if (*v != 7) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, 8, __ATOMIC_RELEASE); ++ if (*v != 15) ++ abort (); ++ ++ count *= 2; ++ __atomic_or_fetch (v, count, __ATOMIC_ACQ_REL); ++ if (*v != 31) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, count, __ATOMIC_SEQ_CST); ++ if (*v != 63) ++ abort (); ++} ++ ++int ++main () ++{ ++ char* V[] = {&A.a, &A.b, &A.c, &A.d}; ++ ++ for (int i = 0; i < 4; i++) { ++ test_fetch_add (V[i]); ++ test_fetch_sub (V[i]); ++ test_fetch_and (V[i]); ++ test_fetch_nand (V[i]); ++ test_fetch_xor (V[i]); ++ test_fetch_or (V[i]); ++ ++ test_add_fetch (V[i]); ++ test_sub_fetch (V[i]); ++ test_and_fetch (V[i]); ++ test_nand_fetch (V[i]); ++ test_xor_fetch (V[i]); ++ test_or_fetch (V[i]); ++ ++ test_add (V[i]); ++ test_sub (V[i]); ++ test_and (V[i]); ++ test_nand (V[i]); ++ test_xor (V[i]); ++ test_or (V[i]); ++ } ++ ++ return 0; ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-4.c +@@ -0,0 +1,566 @@ ++/* Check all short alignments. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-op-2.c */ ++/* Test __atomic routines for existence and proper execution on 2 byte ++ values with each valid memory model. */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics -Wno-address-of-packed-member" } */ ++ ++/* Test the execution of the __atomic_*OP builtin routines for a short. */ ++ ++extern void abort(void); ++ ++short count, res; ++const short init = ~0; ++ ++struct A ++{ ++ short a; ++ short b; ++} __attribute__ ((packed)) A; ++ ++/* The fetch_op routines return the original value before the operation. */ ++ ++void ++test_fetch_add (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_CONSUME) != 1) ++ abort (); ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_ACQUIRE) != 2) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_RELEASE) != 3) ++ abort (); ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_ACQ_REL) != 4) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_SEQ_CST) != 5) ++ abort (); ++} ++ ++ ++void ++test_fetch_sub (short* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_RELAXED) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_CONSUME) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQUIRE) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_RELEASE) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQ_REL) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_SEQ_CST) != res--) ++ abort (); ++} ++ ++void ++test_fetch_and (short* v) ++{ ++ *v = init; ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, init, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_fetch_and (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_fetch_nand (short* v) ++{ ++ *v = init; ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_ACQUIRE) != 0 ) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL) != 0) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++void ++test_fetch_xor (short* v) ++{ ++ *v = init; ++ count = 0; ++ ++ if (__atomic_fetch_xor (v, count, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE) != 0) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++void ++test_fetch_or (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_fetch_or (v, count, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, 2, __ATOMIC_CONSUME) != 1) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_ACQUIRE) != 3) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, 8, __ATOMIC_RELEASE) != 7) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_ACQ_REL) != 15) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_SEQ_CST) != 31) ++ abort (); ++} ++ ++/* The OP_fetch routines return the new value after the operation. */ ++ ++void ++test_add_fetch (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_RELAXED) != 1) ++ abort (); ++ ++ if (__atomic_add_fetch (v, 1, __ATOMIC_CONSUME) != 2) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_ACQUIRE) != 3) ++ abort (); ++ ++ if (__atomic_add_fetch (v, 1, __ATOMIC_RELEASE) != 4) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_ACQ_REL) != 5) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_SEQ_CST) != 6) ++ abort (); ++} ++ ++ ++void ++test_sub_fetch (short* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, 1, __ATOMIC_CONSUME) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQUIRE) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, 1, __ATOMIC_RELEASE) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_SEQ_CST) != --res) ++ abort (); ++} ++ ++void ++test_and_fetch (short* v) ++{ ++ *v = init; ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ *v = init; ++ if (__atomic_and_fetch (v, init, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_and_fetch (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_and_fetch (v, 0, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_nand_fetch (short* v) ++{ ++ *v = init; ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_RELEASE) != 0) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++ ++ ++void ++test_xor_fetch (short* v) ++{ ++ *v = init; ++ count = 0; ++ ++ if (__atomic_xor_fetch (v, count, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_or_fetch (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_or_fetch (v, count, __ATOMIC_RELAXED) != 1) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, 2, __ATOMIC_CONSUME) != 3) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_ACQUIRE) != 7) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, 8, __ATOMIC_RELEASE) != 15) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_ACQ_REL) != 31) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_SEQ_CST) != 63) ++ abort (); ++} ++ ++ ++/* Test the OP routines with a result which isn't used. Use both variations ++ within each function. */ ++ ++void ++test_add (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ __atomic_add_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != 1) ++ abort (); ++ ++ __atomic_fetch_add (v, count, __ATOMIC_CONSUME); ++ if (*v != 2) ++ abort (); ++ ++ __atomic_add_fetch (v, 1 , __ATOMIC_ACQUIRE); ++ if (*v != 3) ++ abort (); ++ ++ __atomic_fetch_add (v, 1, __ATOMIC_RELEASE); ++ if (*v != 4) ++ abort (); ++ ++ __atomic_add_fetch (v, count, __ATOMIC_ACQ_REL); ++ if (*v != 5) ++ abort (); ++ ++ __atomic_fetch_add (v, count, __ATOMIC_SEQ_CST); ++ if (*v != 6) ++ abort (); ++} ++ ++ ++void ++test_sub (short* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ __atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, count + 1, __ATOMIC_CONSUME); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_sub_fetch (v, 1, __ATOMIC_ACQUIRE); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, 1, __ATOMIC_RELEASE); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, count + 1, __ATOMIC_SEQ_CST); ++ if (*v != --res) ++ abort (); ++} ++ ++void ++test_and (short* v) ++{ ++ *v = init; ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_RELAXED); ++ if (*v != 0) ++ abort (); ++ ++ *v = init; ++ __atomic_fetch_and (v, init, __ATOMIC_CONSUME); ++ if (*v != init) ++ abort (); ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != 0) ++ abort (); ++ ++ *v = ~*v; ++ __atomic_fetch_and (v, init, __ATOMIC_RELEASE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL); ++ if (*v != 0) ++ abort (); ++ ++ *v = ~*v; ++ __atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST); ++ if (*v != 0) ++ abort (); ++} ++ ++void ++test_nand (short* v) ++{ ++ *v = init; ++ ++ __atomic_fetch_nand (v, 0, __ATOMIC_RELAXED); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_nand (v, init, __ATOMIC_CONSUME); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_nand_fetch (v, init, __ATOMIC_RELEASE); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL); ++ if (*v != init) ++ abort (); ++ ++ __atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST); ++ if (*v != init) ++ abort (); ++} ++ ++ ++ ++void ++test_xor (short* v) ++{ ++ *v = init; ++ count = 0; ++ ++ __atomic_xor_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL); ++ if (*v != init) ++ abort (); ++ ++ __atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST); ++ if (*v != 0) ++ abort (); ++} ++ ++void ++test_or (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ __atomic_or_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != 1) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, count, __ATOMIC_CONSUME); ++ if (*v != 3) ++ abort (); ++ ++ count *= 2; ++ __atomic_or_fetch (v, 4, __ATOMIC_ACQUIRE); ++ if (*v != 7) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, 8, __ATOMIC_RELEASE); ++ if (*v != 15) ++ abort (); ++ ++ count *= 2; ++ __atomic_or_fetch (v, count, __ATOMIC_ACQ_REL); ++ if (*v != 31) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, count, __ATOMIC_SEQ_CST); ++ if (*v != 63) ++ abort (); ++} ++ ++int ++main () { ++ short* V[] = {&A.a, &A.b}; ++ ++ for (int i = 0; i < 2; i++) { ++ test_fetch_add (V[i]); ++ test_fetch_sub (V[i]); ++ test_fetch_and (V[i]); ++ test_fetch_nand (V[i]); ++ test_fetch_xor (V[i]); ++ test_fetch_or (V[i]); ++ ++ test_add_fetch (V[i]); ++ test_sub_fetch (V[i]); ++ test_and_fetch (V[i]); ++ test_nand_fetch (V[i]); ++ test_xor_fetch (V[i]); ++ test_or_fetch (V[i]); ++ ++ test_add (V[i]); ++ test_sub (V[i]); ++ test_and (V[i]); ++ test_nand (V[i]); ++ test_xor (V[i]); ++ test_or (V[i]); ++ } ++ ++ return 0; ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-5.c +@@ -0,0 +1,87 @@ ++/* Test __atomic routines for existence and proper execution on 1 byte ++ values with each valid memory model. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-compare-exchange-1.c */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics" } */ ++ ++/* Test the execution of the __atomic_compare_exchange_n builtin for a char. */ ++ ++extern void abort(void); ++ ++char v = 0; ++char expected = 0; ++char max = ~0; ++char desired = ~0; ++char zero = 0; ++ ++#define STRONG 0 ++#define WEAK 1 ++ ++int ++main () ++{ ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != max) ++ abort (); ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != max) ++ abort (); ++ if (v != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ if (v != max) ++ abort (); ++ ++ /* Now test the generic version. */ ++ ++ v = 0; ++ ++ if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != max) ++ abort (); ++ ++ if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != max) ++ abort (); ++ if (v != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ if (v != max) ++ abort (); ++ ++ return 0; ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-6.c +@@ -0,0 +1,87 @@ ++/* Test __atomic routines for existence and proper execution on 2 byte ++ values with each valid memory model. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-compare-exchange-2.c */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics" } */ ++ ++/* Test the execution of the __atomic_compare_exchange_n builtin for a short. */ ++ ++extern void abort(void); ++ ++short v = 0; ++short expected = 0; ++short max = ~0; ++short desired = ~0; ++short zero = 0; ++ ++#define STRONG 0 ++#define WEAK 1 ++ ++int ++main () ++{ ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != max) ++ abort (); ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != max) ++ abort (); ++ if (v != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ if (v != max) ++ abort (); ++ ++ /* Now test the generic version. */ ++ ++ v = 0; ++ ++ if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != max) ++ abort (); ++ ++ if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != max) ++ abort (); ++ if (v != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ if (v != max) ++ abort (); ++ ++ return 0; ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-7.c +@@ -0,0 +1,69 @@ ++/* Test __atomic routines for existence and proper execution on 1 byte ++ values with each valid memory model. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-exchange-1.c */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics" } */ ++ ++/* Test the execution of the __atomic_exchange_n builtin for a char. */ ++ ++extern void abort(void); ++ ++char v, count, ret; ++ ++int ++main () ++{ ++ v = 0; ++ count = 0; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELAXED) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQUIRE) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELEASE) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQ_REL) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_SEQ_CST) != count) ++ abort (); ++ count++; ++ ++ /* Now test the generic version. */ ++ ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_RELAXED); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQUIRE); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_RELEASE); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQ_REL); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_SEQ_CST); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ return 0; ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-8.c +@@ -0,0 +1,69 @@ ++/* Test __atomic routines for existence and proper execution on 2 byte ++ values with each valid memory model. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-exchange-2.c */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics" } */ ++ ++/* Test the execution of the __atomic_X builtin for a short. */ ++ ++extern void abort(void); ++ ++short v, count, ret; ++ ++int ++main () ++{ ++ v = 0; ++ count = 0; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELAXED) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQUIRE) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELEASE) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQ_REL) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_SEQ_CST) != count) ++ abort (); ++ count++; ++ ++ /* Now test the generic version. */ ++ ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_RELAXED); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQUIRE); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_RELEASE); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQ_REL); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_SEQ_CST); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ return 0; ++} +--- a/libgcc/config/riscv/atomic.c ++++ b/libgcc/config/riscv/atomic.c +@@ -30,6 +30,8 @@ see the files COPYING3 and COPYING.RUNTI + #define INVERT "not %[tmp1], %[tmp1]\n\t" + #define DONT_INVERT "" + ++/* Logic duplicated in gcc/gcc/config/riscv/sync.md for use when inlining is enabled */ ++ + #define GENERATE_FETCH_AND_OP(type, size, opname, insn, invert, cop) \ + type __sync_fetch_and_ ## opname ## _ ## size (type *p, type v) \ + { \ diff --git a/toolchain/gcc/patches-11.x/701-riscv-linux-Don-t-add-latomic-with-pthread.patch b/toolchain/gcc/patches-11.x/701-riscv-linux-Don-t-add-latomic-with-pthread.patch new file mode 100644 index 00000000000..328c7be9ce8 --- /dev/null +++ b/toolchain/gcc/patches-11.x/701-riscv-linux-Don-t-add-latomic-with-pthread.patch @@ -0,0 +1,36 @@ +From 203f3060dd363361b172f7295f42bb6bf5ac0b3b Mon Sep 17 00:00:00 2001 +From: Andreas Schwab +Date: Sat, 23 Apr 2022 15:48:42 +0200 +Subject: [PATCH] riscv/linux: Don't add -latomic with -pthread + +Now that we have support for inline subword atomic operations, it is no +longer necessary to link against libatomic. This also fixes testsuite +failures because the framework does not properly set up the linker flags +for finding libatomic. +The use of atomic operations is also independent of the use of libpthread. + +gcc/ + * config/riscv/linux.h (LIB_SPEC): Don't redefine. +--- + gcc/config/riscv/linux.h | 10 ---------- + 1 file changed, 10 deletions(-) + +--- a/gcc/config/riscv/linux.h ++++ b/gcc/config/riscv/linux.h +@@ -35,16 +35,6 @@ along with GCC; see the file COPYING3. + #undef MUSL_DYNAMIC_LINKER + #define MUSL_DYNAMIC_LINKER "/lib/ld-musl-riscv" XLEN_SPEC MUSL_ABI_SUFFIX ".so.1" + +-/* Because RISC-V only has word-sized atomics, it requries libatomic where +- others do not. So link libatomic by default, as needed. */ +-#undef LIB_SPEC +-#ifdef LD_AS_NEEDED_OPTION +-#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC \ +- " %{pthread:" LD_AS_NEEDED_OPTION " -latomic " LD_NO_AS_NEEDED_OPTION "}" +-#else +-#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC " -latomic " +-#endif +- + #define ICACHE_FLUSH_FUNC "__riscv_flush_icache" + + #define CPP_SPEC "%{pthread:-D_REENTRANT}" diff --git a/toolchain/gcc/patches-11.x/910-mbsd_multi.patch b/toolchain/gcc/patches-11.x/910-mbsd_multi.patch index 21f532043eb..2d1c3d1b80d 100644 --- a/toolchain/gcc/patches-11.x/910-mbsd_multi.patch +++ b/toolchain/gcc/patches-11.x/910-mbsd_multi.patch @@ -114,7 +114,7 @@ Date: Tue Jul 31 00:52:27 2007 +0000 ; On SVR4 targets, it also controls whether or not to emit a --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi -@@ -9058,6 +9058,17 @@ This option is only supported for C and +@@ -9059,6 +9059,17 @@ This option is only supported for C and @option{-Wall} and by @option{-Wpedantic}, which can be disabled with @option{-Wno-pointer-sign}. diff --git a/toolchain/gcc/patches-12.x/700-RISCV-Inline-subword-atomic-ops.patch b/toolchain/gcc/patches-12.x/700-RISCV-Inline-subword-atomic-ops.patch new file mode 100644 index 00000000000..b164c765222 --- /dev/null +++ b/toolchain/gcc/patches-12.x/700-RISCV-Inline-subword-atomic-ops.patch @@ -0,0 +1,2021 @@ +From f797260adaf52bee0ec0e16190bbefbe1bfc3692 Mon Sep 17 00:00:00 2001 +From: Patrick O'Neill +Date: Tue, 18 Apr 2023 14:33:13 -0700 +Subject: [PATCH] RISCV: Inline subword atomic ops + +RISC-V has no support for subword atomic operations; code currently +generates libatomic library calls. + +This patch changes the default behavior to inline subword atomic calls +(using the same logic as the existing library call). +Behavior can be specified using the -minline-atomics and +-mno-inline-atomics command line flags. + +gcc/libgcc/config/riscv/atomic.c has the same logic implemented in asm. +This will need to stay for backwards compatibility and the +-mno-inline-atomics flag. + +2023-04-18 Patrick O'Neill + +gcc/ChangeLog: + PR target/104338 + * config/riscv/riscv-protos.h: Add helper function stubs. + * config/riscv/riscv.cc: Add helper functions for subword masking. + * config/riscv/riscv.opt: Add command-line flag. + * config/riscv/sync.md: Add masking logic and inline asm for fetch_and_op, + fetch_and_nand, CAS, and exchange ops. + * doc/invoke.texi: Add blurb regarding command-line flag. + +libgcc/ChangeLog: + PR target/104338 + * config/riscv/atomic.c: Add reference to duplicate logic. + +gcc/testsuite/ChangeLog: + PR target/104338 + * gcc.target/riscv/inline-atomics-1.c: New test. + * gcc.target/riscv/inline-atomics-2.c: New test. + * gcc.target/riscv/inline-atomics-3.c: New test. + * gcc.target/riscv/inline-atomics-4.c: New test. + * gcc.target/riscv/inline-atomics-5.c: New test. + * gcc.target/riscv/inline-atomics-6.c: New test. + * gcc.target/riscv/inline-atomics-7.c: New test. + * gcc.target/riscv/inline-atomics-8.c: New test. + +Signed-off-by: Patrick O'Neill +Signed-off-by: Palmer Dabbelt +--- + gcc/config/riscv/riscv-protos.h | 2 + + gcc/config/riscv/riscv.cc | 49 ++ + gcc/config/riscv/riscv.opt | 4 + + gcc/config/riscv/sync.md | 301 +++++++++ + gcc/doc/invoke.texi | 10 +- + .../gcc.target/riscv/inline-atomics-1.c | 18 + + .../gcc.target/riscv/inline-atomics-2.c | 9 + + .../gcc.target/riscv/inline-atomics-3.c | 569 ++++++++++++++++++ + .../gcc.target/riscv/inline-atomics-4.c | 566 +++++++++++++++++ + .../gcc.target/riscv/inline-atomics-5.c | 87 +++ + .../gcc.target/riscv/inline-atomics-6.c | 87 +++ + .../gcc.target/riscv/inline-atomics-7.c | 69 +++ + .../gcc.target/riscv/inline-atomics-8.c | 69 +++ + libgcc/config/riscv/atomic.c | 2 + + 14 files changed, 1841 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-1.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-2.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-3.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-4.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-5.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-6.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-7.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-8.c + +--- a/gcc/config/riscv/riscv-protos.h ++++ b/gcc/config/riscv/riscv-protos.h +@@ -74,6 +74,8 @@ extern bool riscv_expand_block_move (rtx + extern bool riscv_store_data_bypass_p (rtx_insn *, rtx_insn *); + extern rtx riscv_gen_gpr_save_insn (struct riscv_frame_info *); + extern bool riscv_gpr_save_operation_p (rtx); ++extern void riscv_subword_address (rtx, rtx *, rtx *, rtx *, rtx *); ++extern void riscv_lshift_subword (machine_mode, rtx, rtx, rtx *); + + /* Routines implemented in riscv-c.cc. */ + void riscv_cpu_cpp_builtins (cpp_reader *); +--- a/gcc/config/riscv/riscv.cc ++++ b/gcc/config/riscv/riscv.cc +@@ -5605,6 +5605,55 @@ riscv_asan_shadow_offset (void) + return TARGET_64BIT ? (HOST_WIDE_INT_1 << 29) : 0; + } + ++/* Given memory reference MEM, expand code to compute the aligned ++ memory address, shift and mask values and store them into ++ *ALIGNED_MEM, *SHIFT, *MASK and *NOT_MASK. */ ++ ++void ++riscv_subword_address (rtx mem, rtx *aligned_mem, rtx *shift, rtx *mask, ++ rtx *not_mask) ++{ ++ /* Align the memory address to a word. */ ++ rtx addr = force_reg (Pmode, XEXP (mem, 0)); ++ ++ rtx addr_mask = gen_int_mode (-4, Pmode); ++ ++ rtx aligned_addr = gen_reg_rtx (Pmode); ++ emit_move_insn (aligned_addr, gen_rtx_AND (Pmode, addr, addr_mask)); ++ ++ *aligned_mem = change_address (mem, SImode, aligned_addr); ++ ++ /* Calculate the shift amount. */ ++ emit_move_insn (*shift, gen_rtx_AND (SImode, gen_lowpart (SImode, addr), ++ gen_int_mode (3, SImode))); ++ emit_move_insn (*shift, gen_rtx_ASHIFT (SImode, *shift, ++ gen_int_mode (3, SImode))); ++ ++ /* Calculate the mask. */ ++ int unshifted_mask = GET_MODE_MASK (GET_MODE (mem)); ++ ++ emit_move_insn (*mask, gen_int_mode (unshifted_mask, SImode)); ++ ++ emit_move_insn (*mask, gen_rtx_ASHIFT (SImode, *mask, ++ gen_lowpart (QImode, *shift))); ++ ++ emit_move_insn (*not_mask, gen_rtx_NOT(SImode, *mask)); ++} ++ ++/* Leftshift a subword within an SImode register. */ ++ ++void ++riscv_lshift_subword (machine_mode mode, rtx value, rtx shift, ++ rtx *shifted_value) ++{ ++ rtx value_reg = gen_reg_rtx (SImode); ++ emit_move_insn (value_reg, simplify_gen_subreg (SImode, value, ++ mode, 0)); ++ ++ emit_move_insn(*shifted_value, gen_rtx_ASHIFT (SImode, value_reg, ++ gen_lowpart (QImode, shift))); ++} ++ + /* Initialize the GCC target structure. */ + #undef TARGET_ASM_ALIGNED_HI_OP + #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" +--- a/gcc/config/riscv/riscv.opt ++++ b/gcc/config/riscv/riscv.opt +@@ -209,6 +209,10 @@ int riscv_vector_elen_flags + TargetVariable + int riscv_zvl_flags + ++minline-atomics ++Target Var(TARGET_INLINE_SUBWORD_ATOMIC) Init(1) ++Always inline subword atomic operations. ++ + Enum + Name(isa_spec_class) Type(enum riscv_isa_spec_class) + Supported ISA specs (for use with the -misa-spec= option): +--- a/gcc/config/riscv/sync.md ++++ b/gcc/config/riscv/sync.md +@@ -21,8 +21,11 @@ + + (define_c_enum "unspec" [ + UNSPEC_COMPARE_AND_SWAP ++ UNSPEC_COMPARE_AND_SWAP_SUBWORD + UNSPEC_SYNC_OLD_OP ++ UNSPEC_SYNC_OLD_OP_SUBWORD + UNSPEC_SYNC_EXCHANGE ++ UNSPEC_SYNC_EXCHANGE_SUBWORD + UNSPEC_ATOMIC_STORE + UNSPEC_MEMORY_BARRIER + ]) +@@ -92,6 +95,135 @@ + "%F3amo.%A3 %0,%z2,%1" + [(set (attr "length") (const_int 8))]) + ++(define_insn "subword_atomic_fetch_strong_" ++ [(set (match_operand:SI 0 "register_operand" "=&r") ;; old value at mem ++ (match_operand:SI 1 "memory_operand" "+A")) ;; mem location ++ (set (match_dup 1) ++ (unspec_volatile:SI ++ [(any_atomic:SI (match_dup 1) ++ (match_operand:SI 2 "register_operand" "rI")) ;; value for op ++ (match_operand:SI 3 "register_operand" "rI")] ;; mask ++ UNSPEC_SYNC_OLD_OP_SUBWORD)) ++ (match_operand:SI 4 "register_operand" "rI") ;; not_mask ++ (clobber (match_scratch:SI 5 "=&r")) ;; tmp_1 ++ (clobber (match_scratch:SI 6 "=&r"))] ;; tmp_2 ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++ { ++ return "1:\;" ++ "lr.w.aq\t%0, %1\;" ++ "\t%5, %0, %2\;" ++ "and\t%5, %5, %3\;" ++ "and\t%6, %0, %4\;" ++ "or\t%6, %6, %5\;" ++ "sc.w.rl\t%5, %6, %1\;" ++ "bnez\t%5, 1b"; ++ } ++ [(set (attr "length") (const_int 28))]) ++ ++(define_expand "atomic_fetch_nand" ++ [(match_operand:SHORT 0 "register_operand") ;; old value at mem ++ (not:SHORT (and:SHORT (match_operand:SHORT 1 "memory_operand") ;; mem location ++ (match_operand:SHORT 2 "reg_or_0_operand"))) ;; value for op ++ (match_operand:SI 3 "const_int_operand")] ;; model ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ /* We have no QImode/HImode atomics, so form a mask, then use ++ subword_atomic_fetch_strong_nand to implement a LR/SC version of the ++ operation. */ ++ ++ /* Logic duplicated in gcc/libgcc/config/riscv/atomic.c for use when inlining ++ is disabled */ ++ ++ rtx old = gen_reg_rtx (SImode); ++ rtx mem = operands[1]; ++ rtx value = operands[2]; ++ rtx aligned_mem = gen_reg_rtx (SImode); ++ rtx shift = gen_reg_rtx (SImode); ++ rtx mask = gen_reg_rtx (SImode); ++ rtx not_mask = gen_reg_rtx (SImode); ++ ++ riscv_subword_address (mem, &aligned_mem, &shift, &mask, ¬_mask); ++ ++ rtx shifted_value = gen_reg_rtx (SImode); ++ riscv_lshift_subword (mode, value, shift, &shifted_value); ++ ++ emit_insn (gen_subword_atomic_fetch_strong_nand (old, aligned_mem, ++ shifted_value, ++ mask, not_mask)); ++ ++ emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old, ++ gen_lowpart (QImode, shift))); ++ ++ emit_move_insn (operands[0], gen_lowpart (mode, old)); ++ ++ DONE; ++}) ++ ++(define_insn "subword_atomic_fetch_strong_nand" ++ [(set (match_operand:SI 0 "register_operand" "=&r") ;; old value at mem ++ (match_operand:SI 1 "memory_operand" "+A")) ;; mem location ++ (set (match_dup 1) ++ (unspec_volatile:SI ++ [(not:SI (and:SI (match_dup 1) ++ (match_operand:SI 2 "register_operand" "rI"))) ;; value for op ++ (match_operand:SI 3 "register_operand" "rI")] ;; mask ++ UNSPEC_SYNC_OLD_OP_SUBWORD)) ++ (match_operand:SI 4 "register_operand" "rI") ;; not_mask ++ (clobber (match_scratch:SI 5 "=&r")) ;; tmp_1 ++ (clobber (match_scratch:SI 6 "=&r"))] ;; tmp_2 ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++ { ++ return "1:\;" ++ "lr.w.aq\t%0, %1\;" ++ "and\t%5, %0, %2\;" ++ "not\t%5, %5\;" ++ "and\t%5, %5, %3\;" ++ "and\t%6, %0, %4\;" ++ "or\t%6, %6, %5\;" ++ "sc.w.rl\t%5, %6, %1\;" ++ "bnez\t%5, 1b"; ++ } ++ [(set (attr "length") (const_int 32))]) ++ ++(define_expand "atomic_fetch_" ++ [(match_operand:SHORT 0 "register_operand") ;; old value at mem ++ (any_atomic:SHORT (match_operand:SHORT 1 "memory_operand") ;; mem location ++ (match_operand:SHORT 2 "reg_or_0_operand")) ;; value for op ++ (match_operand:SI 3 "const_int_operand")] ;; model ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ /* We have no QImode/HImode atomics, so form a mask, then use ++ subword_atomic_fetch_strong_ to implement a LR/SC version of the ++ operation. */ ++ ++ /* Logic duplicated in gcc/libgcc/config/riscv/atomic.c for use when inlining ++ is disabled */ ++ ++ rtx old = gen_reg_rtx (SImode); ++ rtx mem = operands[1]; ++ rtx value = operands[2]; ++ rtx aligned_mem = gen_reg_rtx (SImode); ++ rtx shift = gen_reg_rtx (SImode); ++ rtx mask = gen_reg_rtx (SImode); ++ rtx not_mask = gen_reg_rtx (SImode); ++ ++ riscv_subword_address (mem, &aligned_mem, &shift, &mask, ¬_mask); ++ ++ rtx shifted_value = gen_reg_rtx (SImode); ++ riscv_lshift_subword (mode, value, shift, &shifted_value); ++ ++ emit_insn (gen_subword_atomic_fetch_strong_ (old, aligned_mem, ++ shifted_value, ++ mask, not_mask)); ++ ++ emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old, ++ gen_lowpart (QImode, shift))); ++ ++ emit_move_insn (operands[0], gen_lowpart (mode, old)); ++ ++ DONE; ++}) ++ + (define_insn "atomic_exchange" + [(set (match_operand:GPR 0 "register_operand" "=&r") + (unspec_volatile:GPR +@@ -104,6 +236,56 @@ + "%F3amoswap.%A3 %0,%z2,%1" + [(set (attr "length") (const_int 8))]) + ++(define_expand "atomic_exchange" ++ [(match_operand:SHORT 0 "register_operand") ;; old value at mem ++ (match_operand:SHORT 1 "memory_operand") ;; mem location ++ (match_operand:SHORT 2 "register_operand") ;; value ++ (match_operand:SI 3 "const_int_operand")] ;; model ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ rtx old = gen_reg_rtx (SImode); ++ rtx mem = operands[1]; ++ rtx value = operands[2]; ++ rtx aligned_mem = gen_reg_rtx (SImode); ++ rtx shift = gen_reg_rtx (SImode); ++ rtx mask = gen_reg_rtx (SImode); ++ rtx not_mask = gen_reg_rtx (SImode); ++ ++ riscv_subword_address (mem, &aligned_mem, &shift, &mask, ¬_mask); ++ ++ rtx shifted_value = gen_reg_rtx (SImode); ++ riscv_lshift_subword (mode, value, shift, &shifted_value); ++ ++ emit_insn (gen_subword_atomic_exchange_strong (old, aligned_mem, ++ shifted_value, not_mask)); ++ ++ emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old, ++ gen_lowpart (QImode, shift))); ++ ++ emit_move_insn (operands[0], gen_lowpart (mode, old)); ++ DONE; ++}) ++ ++(define_insn "subword_atomic_exchange_strong" ++ [(set (match_operand:SI 0 "register_operand" "=&r") ;; old value at mem ++ (match_operand:SI 1 "memory_operand" "+A")) ;; mem location ++ (set (match_dup 1) ++ (unspec_volatile:SI ++ [(match_operand:SI 2 "reg_or_0_operand" "rI") ;; value ++ (match_operand:SI 3 "reg_or_0_operand" "rI")] ;; not_mask ++ UNSPEC_SYNC_EXCHANGE_SUBWORD)) ++ (clobber (match_scratch:SI 4 "=&r"))] ;; tmp_1 ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++ { ++ return "1:\;" ++ "lr.w.aq\t%0, %1\;" ++ "and\t%4, %0, %3\;" ++ "or\t%4, %4, %2\;" ++ "sc.w.rl\t%4, %4, %1\;" ++ "bnez\t%4, 1b"; ++ } ++ [(set (attr "length") (const_int 20))]) ++ + (define_insn "atomic_cas_value_strong" + [(set (match_operand:GPR 0 "register_operand" "=&r") + (match_operand:GPR 1 "memory_operand" "+A")) +@@ -152,6 +334,125 @@ + DONE; + }) + ++(define_expand "atomic_compare_and_swap" ++ [(match_operand:SI 0 "register_operand") ;; bool output ++ (match_operand:SHORT 1 "register_operand") ;; val output ++ (match_operand:SHORT 2 "memory_operand") ;; memory ++ (match_operand:SHORT 3 "reg_or_0_operand") ;; expected value ++ (match_operand:SHORT 4 "reg_or_0_operand") ;; desired value ++ (match_operand:SI 5 "const_int_operand") ;; is_weak ++ (match_operand:SI 6 "const_int_operand") ;; mod_s ++ (match_operand:SI 7 "const_int_operand")] ;; mod_f ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ emit_insn (gen_atomic_cas_value_strong (operands[1], operands[2], ++ operands[3], operands[4], ++ operands[6], operands[7])); ++ ++ rtx val = gen_reg_rtx (SImode); ++ if (operands[1] != const0_rtx) ++ emit_move_insn (val, gen_rtx_SIGN_EXTEND (SImode, operands[1])); ++ else ++ emit_move_insn (val, const0_rtx); ++ ++ rtx exp = gen_reg_rtx (SImode); ++ if (operands[3] != const0_rtx) ++ emit_move_insn (exp, gen_rtx_SIGN_EXTEND (SImode, operands[3])); ++ else ++ emit_move_insn (exp, const0_rtx); ++ ++ rtx compare = val; ++ if (exp != const0_rtx) ++ { ++ rtx difference = gen_rtx_MINUS (SImode, val, exp); ++ compare = gen_reg_rtx (SImode); ++ emit_move_insn (compare, difference); ++ } ++ ++ if (word_mode != SImode) ++ { ++ rtx reg = gen_reg_rtx (word_mode); ++ emit_move_insn (reg, gen_rtx_SIGN_EXTEND (word_mode, compare)); ++ compare = reg; ++ } ++ ++ emit_move_insn (operands[0], gen_rtx_EQ (SImode, compare, const0_rtx)); ++ DONE; ++}) ++ ++(define_expand "atomic_cas_value_strong" ++ [(match_operand:SHORT 0 "register_operand") ;; val output ++ (match_operand:SHORT 1 "memory_operand") ;; memory ++ (match_operand:SHORT 2 "reg_or_0_operand") ;; expected value ++ (match_operand:SHORT 3 "reg_or_0_operand") ;; desired value ++ (match_operand:SI 4 "const_int_operand") ;; mod_s ++ (match_operand:SI 5 "const_int_operand") ;; mod_f ++ (match_scratch:SHORT 6)] ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ /* We have no QImode/HImode atomics, so form a mask, then use ++ subword_atomic_cas_strong to implement a LR/SC version of the ++ operation. */ ++ ++ /* Logic duplicated in gcc/libgcc/config/riscv/atomic.c for use when inlining ++ is disabled */ ++ ++ rtx old = gen_reg_rtx (SImode); ++ rtx mem = operands[1]; ++ rtx aligned_mem = gen_reg_rtx (SImode); ++ rtx shift = gen_reg_rtx (SImode); ++ rtx mask = gen_reg_rtx (SImode); ++ rtx not_mask = gen_reg_rtx (SImode); ++ ++ riscv_subword_address (mem, &aligned_mem, &shift, &mask, ¬_mask); ++ ++ rtx o = operands[2]; ++ rtx n = operands[3]; ++ rtx shifted_o = gen_reg_rtx (SImode); ++ rtx shifted_n = gen_reg_rtx (SImode); ++ ++ riscv_lshift_subword (mode, o, shift, &shifted_o); ++ riscv_lshift_subword (mode, n, shift, &shifted_n); ++ ++ emit_move_insn (shifted_o, gen_rtx_AND (SImode, shifted_o, mask)); ++ emit_move_insn (shifted_n, gen_rtx_AND (SImode, shifted_n, mask)); ++ ++ emit_insn (gen_subword_atomic_cas_strong (old, aligned_mem, ++ shifted_o, shifted_n, ++ mask, not_mask)); ++ ++ emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old, ++ gen_lowpart (QImode, shift))); ++ ++ emit_move_insn (operands[0], gen_lowpart (mode, old)); ++ ++ DONE; ++}) ++ ++(define_insn "subword_atomic_cas_strong" ++ [(set (match_operand:SI 0 "register_operand" "=&r") ;; old value at mem ++ (match_operand:SI 1 "memory_operand" "+A")) ;; mem location ++ (set (match_dup 1) ++ (unspec_volatile:SI [(match_operand:SI 2 "reg_or_0_operand" "rJ") ;; expected value ++ (match_operand:SI 3 "reg_or_0_operand" "rJ")] ;; desired value ++ UNSPEC_COMPARE_AND_SWAP_SUBWORD)) ++ (match_operand:SI 4 "register_operand" "rI") ;; mask ++ (match_operand:SI 5 "register_operand" "rI") ;; not_mask ++ (clobber (match_scratch:SI 6 "=&r"))] ;; tmp_1 ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++ { ++ return "1:\;" ++ "lr.w.aq\t%0, %1\;" ++ "and\t%6, %0, %4\;" ++ "bne\t%6, %z2, 1f\;" ++ "and\t%6, %0, %5\;" ++ "or\t%6, %6, %3\;" ++ "sc.w.rl\t%6, %6, %1\;" ++ "bnez\t%6, 1b\;" ++ "1:"; ++ } ++ [(set (attr "length") (const_int 28))]) ++ + (define_expand "atomic_test_and_set" + [(match_operand:QI 0 "register_operand" "") ;; bool output + (match_operand:QI 1 "memory_operand" "+A") ;; memory +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -753,7 +753,8 @@ Objective-C and Objective-C++ Dialects}. + -moverride=@var{string} -mverbose-cost-dump @gol + -mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{sysreg} @gol + -mstack-protector-guard-offset=@var{offset} -mtrack-speculation @gol +--moutline-atomics } ++-moutline-atomics ++-minline-atomics -mno-inline-atomics} + + @emph{Adapteva Epiphany Options} + @gccoptlist{-mhalf-reg-file -mprefer-short-insn-regs @gol +@@ -28035,6 +28036,13 @@ Do or don't use smaller but slower prolo + library function calls. The default is to use fast inline prologues and + epilogues. + ++@opindex minline-atomics ++@item -minline-atomics ++@itemx -mno-inline-atomics ++Do or don't use smaller but slower subword atomic emulation code that uses ++libatomic function calls. The default is to use fast inline subword atomics ++that do not require libatomic. ++ + @item -mshorten-memrefs + @itemx -mno-shorten-memrefs + @opindex mshorten-memrefs +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-1.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mno-inline-atomics" } */ ++/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "fetch_and_nand" { target *-*-* } 0 } */ ++/* { dg-final { scan-assembler "\tcall\t__sync_fetch_and_add_1" } } */ ++/* { dg-final { scan-assembler "\tcall\t__sync_fetch_and_nand_1" } } */ ++/* { dg-final { scan-assembler "\tcall\t__sync_bool_compare_and_swap_1" } } */ ++ ++char foo; ++char bar; ++char baz; ++ ++int ++main () ++{ ++ __sync_fetch_and_add(&foo, 1); ++ __sync_fetch_and_nand(&bar, 1); ++ __sync_bool_compare_and_swap (&baz, 1, 2); ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-2.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile } */ ++/* Verify that subword atomics do not generate calls. */ ++/* { dg-options "-minline-atomics" } */ ++/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "fetch_and_nand" { target *-*-* } 0 } */ ++/* { dg-final { scan-assembler-not "\tcall\t__sync_fetch_and_add_1" } } */ ++/* { dg-final { scan-assembler-not "\tcall\t__sync_fetch_and_nand_1" } } */ ++/* { dg-final { scan-assembler-not "\tcall\t__sync_bool_compare_and_swap_1" } } */ ++ ++#include "inline-atomics-1.c" +\ No newline at end of file +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-3.c +@@ -0,0 +1,569 @@ ++/* Check all char alignments. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-op-1.c */ ++/* Test __atomic routines for existence and proper execution on 1 byte ++ values with each valid memory model. */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics -Wno-address-of-packed-member" } */ ++ ++/* Test the execution of the __atomic_*OP builtin routines for a char. */ ++ ++extern void abort(void); ++ ++char count, res; ++const char init = ~0; ++ ++struct A ++{ ++ char a; ++ char b; ++ char c; ++ char d; ++} __attribute__ ((packed)) A; ++ ++/* The fetch_op routines return the original value before the operation. */ ++ ++void ++test_fetch_add (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_CONSUME) != 1) ++ abort (); ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_ACQUIRE) != 2) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_RELEASE) != 3) ++ abort (); ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_ACQ_REL) != 4) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_SEQ_CST) != 5) ++ abort (); ++} ++ ++ ++void ++test_fetch_sub (char* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_RELAXED) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_CONSUME) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQUIRE) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_RELEASE) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQ_REL) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_SEQ_CST) != res--) ++ abort (); ++} ++ ++void ++test_fetch_and (char* v) ++{ ++ *v = init; ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, init, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_fetch_and (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_fetch_nand (char* v) ++{ ++ *v = init; ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_ACQUIRE) != 0 ) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL) != 0) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++void ++test_fetch_xor (char* v) ++{ ++ *v = init; ++ count = 0; ++ ++ if (__atomic_fetch_xor (v, count, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE) != 0) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++void ++test_fetch_or (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_fetch_or (v, count, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, 2, __ATOMIC_CONSUME) != 1) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_ACQUIRE) != 3) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, 8, __ATOMIC_RELEASE) != 7) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_ACQ_REL) != 15) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_SEQ_CST) != 31) ++ abort (); ++} ++ ++/* The OP_fetch routines return the new value after the operation. */ ++ ++void ++test_add_fetch (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_RELAXED) != 1) ++ abort (); ++ ++ if (__atomic_add_fetch (v, 1, __ATOMIC_CONSUME) != 2) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_ACQUIRE) != 3) ++ abort (); ++ ++ if (__atomic_add_fetch (v, 1, __ATOMIC_RELEASE) != 4) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_ACQ_REL) != 5) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_SEQ_CST) != 6) ++ abort (); ++} ++ ++ ++void ++test_sub_fetch (char* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, 1, __ATOMIC_CONSUME) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQUIRE) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, 1, __ATOMIC_RELEASE) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_SEQ_CST) != --res) ++ abort (); ++} ++ ++void ++test_and_fetch (char* v) ++{ ++ *v = init; ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ *v = init; ++ if (__atomic_and_fetch (v, init, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_and_fetch (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_and_fetch (v, 0, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_nand_fetch (char* v) ++{ ++ *v = init; ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_RELEASE) != 0) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++ ++ ++void ++test_xor_fetch (char* v) ++{ ++ *v = init; ++ count = 0; ++ ++ if (__atomic_xor_fetch (v, count, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_or_fetch (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_or_fetch (v, count, __ATOMIC_RELAXED) != 1) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, 2, __ATOMIC_CONSUME) != 3) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_ACQUIRE) != 7) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, 8, __ATOMIC_RELEASE) != 15) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_ACQ_REL) != 31) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_SEQ_CST) != 63) ++ abort (); ++} ++ ++ ++/* Test the OP routines with a result which isn't used. Use both variations ++ within each function. */ ++ ++void ++test_add (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ __atomic_add_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != 1) ++ abort (); ++ ++ __atomic_fetch_add (v, count, __ATOMIC_CONSUME); ++ if (*v != 2) ++ abort (); ++ ++ __atomic_add_fetch (v, 1 , __ATOMIC_ACQUIRE); ++ if (*v != 3) ++ abort (); ++ ++ __atomic_fetch_add (v, 1, __ATOMIC_RELEASE); ++ if (*v != 4) ++ abort (); ++ ++ __atomic_add_fetch (v, count, __ATOMIC_ACQ_REL); ++ if (*v != 5) ++ abort (); ++ ++ __atomic_fetch_add (v, count, __ATOMIC_SEQ_CST); ++ if (*v != 6) ++ abort (); ++} ++ ++ ++void ++test_sub (char* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ __atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, count + 1, __ATOMIC_CONSUME); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_sub_fetch (v, 1, __ATOMIC_ACQUIRE); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, 1, __ATOMIC_RELEASE); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, count + 1, __ATOMIC_SEQ_CST); ++ if (*v != --res) ++ abort (); ++} ++ ++void ++test_and (char* v) ++{ ++ *v = init; ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_RELAXED); ++ if (*v != 0) ++ abort (); ++ ++ *v = init; ++ __atomic_fetch_and (v, init, __ATOMIC_CONSUME); ++ if (*v != init) ++ abort (); ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != 0) ++ abort (); ++ ++ *v = ~*v; ++ __atomic_fetch_and (v, init, __ATOMIC_RELEASE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL); ++ if (*v != 0) ++ abort (); ++ ++ *v = ~*v; ++ __atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST); ++ if (*v != 0) ++ abort (); ++} ++ ++void ++test_nand (char* v) ++{ ++ *v = init; ++ ++ __atomic_fetch_nand (v, 0, __ATOMIC_RELAXED); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_nand (v, init, __ATOMIC_CONSUME); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_nand_fetch (v, init, __ATOMIC_RELEASE); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL); ++ if (*v != init) ++ abort (); ++ ++ __atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST); ++ if (*v != init) ++ abort (); ++} ++ ++ ++ ++void ++test_xor (char* v) ++{ ++ *v = init; ++ count = 0; ++ ++ __atomic_xor_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL); ++ if (*v != init) ++ abort (); ++ ++ __atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST); ++ if (*v != 0) ++ abort (); ++} ++ ++void ++test_or (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ __atomic_or_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != 1) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, count, __ATOMIC_CONSUME); ++ if (*v != 3) ++ abort (); ++ ++ count *= 2; ++ __atomic_or_fetch (v, 4, __ATOMIC_ACQUIRE); ++ if (*v != 7) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, 8, __ATOMIC_RELEASE); ++ if (*v != 15) ++ abort (); ++ ++ count *= 2; ++ __atomic_or_fetch (v, count, __ATOMIC_ACQ_REL); ++ if (*v != 31) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, count, __ATOMIC_SEQ_CST); ++ if (*v != 63) ++ abort (); ++} ++ ++int ++main () ++{ ++ char* V[] = {&A.a, &A.b, &A.c, &A.d}; ++ ++ for (int i = 0; i < 4; i++) { ++ test_fetch_add (V[i]); ++ test_fetch_sub (V[i]); ++ test_fetch_and (V[i]); ++ test_fetch_nand (V[i]); ++ test_fetch_xor (V[i]); ++ test_fetch_or (V[i]); ++ ++ test_add_fetch (V[i]); ++ test_sub_fetch (V[i]); ++ test_and_fetch (V[i]); ++ test_nand_fetch (V[i]); ++ test_xor_fetch (V[i]); ++ test_or_fetch (V[i]); ++ ++ test_add (V[i]); ++ test_sub (V[i]); ++ test_and (V[i]); ++ test_nand (V[i]); ++ test_xor (V[i]); ++ test_or (V[i]); ++ } ++ ++ return 0; ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-4.c +@@ -0,0 +1,566 @@ ++/* Check all short alignments. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-op-2.c */ ++/* Test __atomic routines for existence and proper execution on 2 byte ++ values with each valid memory model. */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics -Wno-address-of-packed-member" } */ ++ ++/* Test the execution of the __atomic_*OP builtin routines for a short. */ ++ ++extern void abort(void); ++ ++short count, res; ++const short init = ~0; ++ ++struct A ++{ ++ short a; ++ short b; ++} __attribute__ ((packed)) A; ++ ++/* The fetch_op routines return the original value before the operation. */ ++ ++void ++test_fetch_add (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_CONSUME) != 1) ++ abort (); ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_ACQUIRE) != 2) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_RELEASE) != 3) ++ abort (); ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_ACQ_REL) != 4) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_SEQ_CST) != 5) ++ abort (); ++} ++ ++ ++void ++test_fetch_sub (short* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_RELAXED) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_CONSUME) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQUIRE) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_RELEASE) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQ_REL) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_SEQ_CST) != res--) ++ abort (); ++} ++ ++void ++test_fetch_and (short* v) ++{ ++ *v = init; ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, init, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_fetch_and (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_fetch_nand (short* v) ++{ ++ *v = init; ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_ACQUIRE) != 0 ) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL) != 0) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++void ++test_fetch_xor (short* v) ++{ ++ *v = init; ++ count = 0; ++ ++ if (__atomic_fetch_xor (v, count, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE) != 0) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++void ++test_fetch_or (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_fetch_or (v, count, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, 2, __ATOMIC_CONSUME) != 1) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_ACQUIRE) != 3) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, 8, __ATOMIC_RELEASE) != 7) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_ACQ_REL) != 15) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_SEQ_CST) != 31) ++ abort (); ++} ++ ++/* The OP_fetch routines return the new value after the operation. */ ++ ++void ++test_add_fetch (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_RELAXED) != 1) ++ abort (); ++ ++ if (__atomic_add_fetch (v, 1, __ATOMIC_CONSUME) != 2) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_ACQUIRE) != 3) ++ abort (); ++ ++ if (__atomic_add_fetch (v, 1, __ATOMIC_RELEASE) != 4) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_ACQ_REL) != 5) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_SEQ_CST) != 6) ++ abort (); ++} ++ ++ ++void ++test_sub_fetch (short* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, 1, __ATOMIC_CONSUME) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQUIRE) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, 1, __ATOMIC_RELEASE) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_SEQ_CST) != --res) ++ abort (); ++} ++ ++void ++test_and_fetch (short* v) ++{ ++ *v = init; ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ *v = init; ++ if (__atomic_and_fetch (v, init, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_and_fetch (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_and_fetch (v, 0, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_nand_fetch (short* v) ++{ ++ *v = init; ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_RELEASE) != 0) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++ ++ ++void ++test_xor_fetch (short* v) ++{ ++ *v = init; ++ count = 0; ++ ++ if (__atomic_xor_fetch (v, count, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_or_fetch (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_or_fetch (v, count, __ATOMIC_RELAXED) != 1) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, 2, __ATOMIC_CONSUME) != 3) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_ACQUIRE) != 7) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, 8, __ATOMIC_RELEASE) != 15) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_ACQ_REL) != 31) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_SEQ_CST) != 63) ++ abort (); ++} ++ ++ ++/* Test the OP routines with a result which isn't used. Use both variations ++ within each function. */ ++ ++void ++test_add (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ __atomic_add_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != 1) ++ abort (); ++ ++ __atomic_fetch_add (v, count, __ATOMIC_CONSUME); ++ if (*v != 2) ++ abort (); ++ ++ __atomic_add_fetch (v, 1 , __ATOMIC_ACQUIRE); ++ if (*v != 3) ++ abort (); ++ ++ __atomic_fetch_add (v, 1, __ATOMIC_RELEASE); ++ if (*v != 4) ++ abort (); ++ ++ __atomic_add_fetch (v, count, __ATOMIC_ACQ_REL); ++ if (*v != 5) ++ abort (); ++ ++ __atomic_fetch_add (v, count, __ATOMIC_SEQ_CST); ++ if (*v != 6) ++ abort (); ++} ++ ++ ++void ++test_sub (short* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ __atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, count + 1, __ATOMIC_CONSUME); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_sub_fetch (v, 1, __ATOMIC_ACQUIRE); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, 1, __ATOMIC_RELEASE); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, count + 1, __ATOMIC_SEQ_CST); ++ if (*v != --res) ++ abort (); ++} ++ ++void ++test_and (short* v) ++{ ++ *v = init; ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_RELAXED); ++ if (*v != 0) ++ abort (); ++ ++ *v = init; ++ __atomic_fetch_and (v, init, __ATOMIC_CONSUME); ++ if (*v != init) ++ abort (); ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != 0) ++ abort (); ++ ++ *v = ~*v; ++ __atomic_fetch_and (v, init, __ATOMIC_RELEASE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL); ++ if (*v != 0) ++ abort (); ++ ++ *v = ~*v; ++ __atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST); ++ if (*v != 0) ++ abort (); ++} ++ ++void ++test_nand (short* v) ++{ ++ *v = init; ++ ++ __atomic_fetch_nand (v, 0, __ATOMIC_RELAXED); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_nand (v, init, __ATOMIC_CONSUME); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_nand_fetch (v, init, __ATOMIC_RELEASE); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL); ++ if (*v != init) ++ abort (); ++ ++ __atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST); ++ if (*v != init) ++ abort (); ++} ++ ++ ++ ++void ++test_xor (short* v) ++{ ++ *v = init; ++ count = 0; ++ ++ __atomic_xor_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL); ++ if (*v != init) ++ abort (); ++ ++ __atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST); ++ if (*v != 0) ++ abort (); ++} ++ ++void ++test_or (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ __atomic_or_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != 1) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, count, __ATOMIC_CONSUME); ++ if (*v != 3) ++ abort (); ++ ++ count *= 2; ++ __atomic_or_fetch (v, 4, __ATOMIC_ACQUIRE); ++ if (*v != 7) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, 8, __ATOMIC_RELEASE); ++ if (*v != 15) ++ abort (); ++ ++ count *= 2; ++ __atomic_or_fetch (v, count, __ATOMIC_ACQ_REL); ++ if (*v != 31) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, count, __ATOMIC_SEQ_CST); ++ if (*v != 63) ++ abort (); ++} ++ ++int ++main () { ++ short* V[] = {&A.a, &A.b}; ++ ++ for (int i = 0; i < 2; i++) { ++ test_fetch_add (V[i]); ++ test_fetch_sub (V[i]); ++ test_fetch_and (V[i]); ++ test_fetch_nand (V[i]); ++ test_fetch_xor (V[i]); ++ test_fetch_or (V[i]); ++ ++ test_add_fetch (V[i]); ++ test_sub_fetch (V[i]); ++ test_and_fetch (V[i]); ++ test_nand_fetch (V[i]); ++ test_xor_fetch (V[i]); ++ test_or_fetch (V[i]); ++ ++ test_add (V[i]); ++ test_sub (V[i]); ++ test_and (V[i]); ++ test_nand (V[i]); ++ test_xor (V[i]); ++ test_or (V[i]); ++ } ++ ++ return 0; ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-5.c +@@ -0,0 +1,87 @@ ++/* Test __atomic routines for existence and proper execution on 1 byte ++ values with each valid memory model. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-compare-exchange-1.c */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics" } */ ++ ++/* Test the execution of the __atomic_compare_exchange_n builtin for a char. */ ++ ++extern void abort(void); ++ ++char v = 0; ++char expected = 0; ++char max = ~0; ++char desired = ~0; ++char zero = 0; ++ ++#define STRONG 0 ++#define WEAK 1 ++ ++int ++main () ++{ ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != max) ++ abort (); ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != max) ++ abort (); ++ if (v != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ if (v != max) ++ abort (); ++ ++ /* Now test the generic version. */ ++ ++ v = 0; ++ ++ if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != max) ++ abort (); ++ ++ if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != max) ++ abort (); ++ if (v != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ if (v != max) ++ abort (); ++ ++ return 0; ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-6.c +@@ -0,0 +1,87 @@ ++/* Test __atomic routines for existence and proper execution on 2 byte ++ values with each valid memory model. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-compare-exchange-2.c */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics" } */ ++ ++/* Test the execution of the __atomic_compare_exchange_n builtin for a short. */ ++ ++extern void abort(void); ++ ++short v = 0; ++short expected = 0; ++short max = ~0; ++short desired = ~0; ++short zero = 0; ++ ++#define STRONG 0 ++#define WEAK 1 ++ ++int ++main () ++{ ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != max) ++ abort (); ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != max) ++ abort (); ++ if (v != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ if (v != max) ++ abort (); ++ ++ /* Now test the generic version. */ ++ ++ v = 0; ++ ++ if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != max) ++ abort (); ++ ++ if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != max) ++ abort (); ++ if (v != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ if (v != max) ++ abort (); ++ ++ return 0; ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-7.c +@@ -0,0 +1,69 @@ ++/* Test __atomic routines for existence and proper execution on 1 byte ++ values with each valid memory model. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-exchange-1.c */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics" } */ ++ ++/* Test the execution of the __atomic_exchange_n builtin for a char. */ ++ ++extern void abort(void); ++ ++char v, count, ret; ++ ++int ++main () ++{ ++ v = 0; ++ count = 0; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELAXED) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQUIRE) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELEASE) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQ_REL) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_SEQ_CST) != count) ++ abort (); ++ count++; ++ ++ /* Now test the generic version. */ ++ ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_RELAXED); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQUIRE); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_RELEASE); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQ_REL); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_SEQ_CST); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ return 0; ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-8.c +@@ -0,0 +1,69 @@ ++/* Test __atomic routines for existence and proper execution on 2 byte ++ values with each valid memory model. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-exchange-2.c */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics" } */ ++ ++/* Test the execution of the __atomic_X builtin for a short. */ ++ ++extern void abort(void); ++ ++short v, count, ret; ++ ++int ++main () ++{ ++ v = 0; ++ count = 0; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELAXED) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQUIRE) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELEASE) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQ_REL) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_SEQ_CST) != count) ++ abort (); ++ count++; ++ ++ /* Now test the generic version. */ ++ ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_RELAXED); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQUIRE); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_RELEASE); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQ_REL); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_SEQ_CST); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ return 0; ++} +--- a/libgcc/config/riscv/atomic.c ++++ b/libgcc/config/riscv/atomic.c +@@ -30,6 +30,8 @@ see the files COPYING3 and COPYING.RUNTI + #define INVERT "not %[tmp1], %[tmp1]\n\t" + #define DONT_INVERT "" + ++/* Logic duplicated in gcc/gcc/config/riscv/sync.md for use when inlining is enabled */ ++ + #define GENERATE_FETCH_AND_OP(type, size, opname, insn, invert, cop) \ + type __sync_fetch_and_ ## opname ## _ ## size (type *p, type v) \ + { \ diff --git a/toolchain/gcc/patches-12.x/701-riscv-linux-Don-t-add-latomic-with-pthread.patch b/toolchain/gcc/patches-12.x/701-riscv-linux-Don-t-add-latomic-with-pthread.patch new file mode 100644 index 00000000000..328c7be9ce8 --- /dev/null +++ b/toolchain/gcc/patches-12.x/701-riscv-linux-Don-t-add-latomic-with-pthread.patch @@ -0,0 +1,36 @@ +From 203f3060dd363361b172f7295f42bb6bf5ac0b3b Mon Sep 17 00:00:00 2001 +From: Andreas Schwab +Date: Sat, 23 Apr 2022 15:48:42 +0200 +Subject: [PATCH] riscv/linux: Don't add -latomic with -pthread + +Now that we have support for inline subword atomic operations, it is no +longer necessary to link against libatomic. This also fixes testsuite +failures because the framework does not properly set up the linker flags +for finding libatomic. +The use of atomic operations is also independent of the use of libpthread. + +gcc/ + * config/riscv/linux.h (LIB_SPEC): Don't redefine. +--- + gcc/config/riscv/linux.h | 10 ---------- + 1 file changed, 10 deletions(-) + +--- a/gcc/config/riscv/linux.h ++++ b/gcc/config/riscv/linux.h +@@ -35,16 +35,6 @@ along with GCC; see the file COPYING3. + #undef MUSL_DYNAMIC_LINKER + #define MUSL_DYNAMIC_LINKER "/lib/ld-musl-riscv" XLEN_SPEC MUSL_ABI_SUFFIX ".so.1" + +-/* Because RISC-V only has word-sized atomics, it requries libatomic where +- others do not. So link libatomic by default, as needed. */ +-#undef LIB_SPEC +-#ifdef LD_AS_NEEDED_OPTION +-#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC \ +- " %{pthread:" LD_AS_NEEDED_OPTION " -latomic " LD_NO_AS_NEEDED_OPTION "}" +-#else +-#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC " -latomic " +-#endif +- + #define ICACHE_FLUSH_FUNC "__riscv_flush_icache" + + #define CPP_SPEC "%{pthread:-D_REENTRANT}" diff --git a/toolchain/gcc/patches-12.x/910-mbsd_multi.patch b/toolchain/gcc/patches-12.x/910-mbsd_multi.patch index 0f75d0ce0eb..9233c6a1d78 100644 --- a/toolchain/gcc/patches-12.x/910-mbsd_multi.patch +++ b/toolchain/gcc/patches-12.x/910-mbsd_multi.patch @@ -114,7 +114,7 @@ Date: Tue Jul 31 00:52:27 2007 +0000 ; On SVR4 targets, it also controls whether or not to emit a --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi -@@ -9596,6 +9596,17 @@ This option is only supported for C and +@@ -9597,6 +9597,17 @@ This option is only supported for C and @option{-Wall} and by @option{-Wpedantic}, which can be disabled with @option{-Wno-pointer-sign}. diff --git a/toolchain/gcc/patches-13.x/700-RISCV-Inline-subword-atomic-ops.patch b/toolchain/gcc/patches-13.x/700-RISCV-Inline-subword-atomic-ops.patch new file mode 100644 index 00000000000..752480bc4c5 --- /dev/null +++ b/toolchain/gcc/patches-13.x/700-RISCV-Inline-subword-atomic-ops.patch @@ -0,0 +1,2021 @@ +From f797260adaf52bee0ec0e16190bbefbe1bfc3692 Mon Sep 17 00:00:00 2001 +From: Patrick O'Neill +Date: Tue, 18 Apr 2023 14:33:13 -0700 +Subject: [PATCH] RISCV: Inline subword atomic ops + +RISC-V has no support for subword atomic operations; code currently +generates libatomic library calls. + +This patch changes the default behavior to inline subword atomic calls +(using the same logic as the existing library call). +Behavior can be specified using the -minline-atomics and +-mno-inline-atomics command line flags. + +gcc/libgcc/config/riscv/atomic.c has the same logic implemented in asm. +This will need to stay for backwards compatibility and the +-mno-inline-atomics flag. + +2023-04-18 Patrick O'Neill + +gcc/ChangeLog: + PR target/104338 + * config/riscv/riscv-protos.h: Add helper function stubs. + * config/riscv/riscv.cc: Add helper functions for subword masking. + * config/riscv/riscv.opt: Add command-line flag. + * config/riscv/sync.md: Add masking logic and inline asm for fetch_and_op, + fetch_and_nand, CAS, and exchange ops. + * doc/invoke.texi: Add blurb regarding command-line flag. + +libgcc/ChangeLog: + PR target/104338 + * config/riscv/atomic.c: Add reference to duplicate logic. + +gcc/testsuite/ChangeLog: + PR target/104338 + * gcc.target/riscv/inline-atomics-1.c: New test. + * gcc.target/riscv/inline-atomics-2.c: New test. + * gcc.target/riscv/inline-atomics-3.c: New test. + * gcc.target/riscv/inline-atomics-4.c: New test. + * gcc.target/riscv/inline-atomics-5.c: New test. + * gcc.target/riscv/inline-atomics-6.c: New test. + * gcc.target/riscv/inline-atomics-7.c: New test. + * gcc.target/riscv/inline-atomics-8.c: New test. + +Signed-off-by: Patrick O'Neill +Signed-off-by: Palmer Dabbelt +--- + gcc/config/riscv/riscv-protos.h | 2 + + gcc/config/riscv/riscv.cc | 49 ++ + gcc/config/riscv/riscv.opt | 4 + + gcc/config/riscv/sync.md | 301 +++++++++ + gcc/doc/invoke.texi | 10 +- + .../gcc.target/riscv/inline-atomics-1.c | 18 + + .../gcc.target/riscv/inline-atomics-2.c | 9 + + .../gcc.target/riscv/inline-atomics-3.c | 569 ++++++++++++++++++ + .../gcc.target/riscv/inline-atomics-4.c | 566 +++++++++++++++++ + .../gcc.target/riscv/inline-atomics-5.c | 87 +++ + .../gcc.target/riscv/inline-atomics-6.c | 87 +++ + .../gcc.target/riscv/inline-atomics-7.c | 69 +++ + .../gcc.target/riscv/inline-atomics-8.c | 69 +++ + libgcc/config/riscv/atomic.c | 2 + + 14 files changed, 1841 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-1.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-2.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-3.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-4.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-5.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-6.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-7.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-8.c + +--- a/gcc/config/riscv/riscv-protos.h ++++ b/gcc/config/riscv/riscv-protos.h +@@ -79,6 +79,8 @@ extern void riscv_reinit (void); + extern poly_uint64 riscv_regmode_natural_size (machine_mode); + extern bool riscv_v_ext_vector_mode_p (machine_mode); + extern bool riscv_shamt_matches_mask_p (int, HOST_WIDE_INT); ++extern void riscv_subword_address (rtx, rtx *, rtx *, rtx *, rtx *); ++extern void riscv_lshift_subword (machine_mode, rtx, rtx, rtx *); + + /* Routines implemented in riscv-c.cc. */ + void riscv_cpu_cpp_builtins (cpp_reader *); +--- a/gcc/config/riscv/riscv.cc ++++ b/gcc/config/riscv/riscv.cc +@@ -7143,6 +7143,55 @@ riscv_zero_call_used_regs (HARD_REG_SET + & ~zeroed_hardregs); + } + ++/* Given memory reference MEM, expand code to compute the aligned ++ memory address, shift and mask values and store them into ++ *ALIGNED_MEM, *SHIFT, *MASK and *NOT_MASK. */ ++ ++void ++riscv_subword_address (rtx mem, rtx *aligned_mem, rtx *shift, rtx *mask, ++ rtx *not_mask) ++{ ++ /* Align the memory address to a word. */ ++ rtx addr = force_reg (Pmode, XEXP (mem, 0)); ++ ++ rtx addr_mask = gen_int_mode (-4, Pmode); ++ ++ rtx aligned_addr = gen_reg_rtx (Pmode); ++ emit_move_insn (aligned_addr, gen_rtx_AND (Pmode, addr, addr_mask)); ++ ++ *aligned_mem = change_address (mem, SImode, aligned_addr); ++ ++ /* Calculate the shift amount. */ ++ emit_move_insn (*shift, gen_rtx_AND (SImode, gen_lowpart (SImode, addr), ++ gen_int_mode (3, SImode))); ++ emit_move_insn (*shift, gen_rtx_ASHIFT (SImode, *shift, ++ gen_int_mode (3, SImode))); ++ ++ /* Calculate the mask. */ ++ int unshifted_mask = GET_MODE_MASK (GET_MODE (mem)); ++ ++ emit_move_insn (*mask, gen_int_mode (unshifted_mask, SImode)); ++ ++ emit_move_insn (*mask, gen_rtx_ASHIFT (SImode, *mask, ++ gen_lowpart (QImode, *shift))); ++ ++ emit_move_insn (*not_mask, gen_rtx_NOT(SImode, *mask)); ++} ++ ++/* Leftshift a subword within an SImode register. */ ++ ++void ++riscv_lshift_subword (machine_mode mode, rtx value, rtx shift, ++ rtx *shifted_value) ++{ ++ rtx value_reg = gen_reg_rtx (SImode); ++ emit_move_insn (value_reg, simplify_gen_subreg (SImode, value, ++ mode, 0)); ++ ++ emit_move_insn(*shifted_value, gen_rtx_ASHIFT (SImode, value_reg, ++ gen_lowpart (QImode, shift))); ++} ++ + /* Initialize the GCC target structure. */ + #undef TARGET_ASM_ALIGNED_HI_OP + #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" +--- a/gcc/config/riscv/riscv.opt ++++ b/gcc/config/riscv/riscv.opt +@@ -238,6 +238,10 @@ int riscv_sv_subext + TargetVariable + int riscv_xthead_subext + ++minline-atomics ++Target Var(TARGET_INLINE_SUBWORD_ATOMIC) Init(1) ++Always inline subword atomic operations. ++ + Enum + Name(isa_spec_class) Type(enum riscv_isa_spec_class) + Supported ISA specs (for use with the -misa-spec= option): +--- a/gcc/config/riscv/sync.md ++++ b/gcc/config/riscv/sync.md +@@ -21,8 +21,11 @@ + + (define_c_enum "unspec" [ + UNSPEC_COMPARE_AND_SWAP ++ UNSPEC_COMPARE_AND_SWAP_SUBWORD + UNSPEC_SYNC_OLD_OP ++ UNSPEC_SYNC_OLD_OP_SUBWORD + UNSPEC_SYNC_EXCHANGE ++ UNSPEC_SYNC_EXCHANGE_SUBWORD + UNSPEC_ATOMIC_STORE + UNSPEC_MEMORY_BARRIER + ]) +@@ -91,6 +94,135 @@ + [(set_attr "type" "atomic") + (set (attr "length") (const_int 8))]) + ++(define_insn "subword_atomic_fetch_strong_" ++ [(set (match_operand:SI 0 "register_operand" "=&r") ;; old value at mem ++ (match_operand:SI 1 "memory_operand" "+A")) ;; mem location ++ (set (match_dup 1) ++ (unspec_volatile:SI ++ [(any_atomic:SI (match_dup 1) ++ (match_operand:SI 2 "register_operand" "rI")) ;; value for op ++ (match_operand:SI 3 "register_operand" "rI")] ;; mask ++ UNSPEC_SYNC_OLD_OP_SUBWORD)) ++ (match_operand:SI 4 "register_operand" "rI") ;; not_mask ++ (clobber (match_scratch:SI 5 "=&r")) ;; tmp_1 ++ (clobber (match_scratch:SI 6 "=&r"))] ;; tmp_2 ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++ { ++ return "1:\;" ++ "lr.w.aq\t%0, %1\;" ++ "\t%5, %0, %2\;" ++ "and\t%5, %5, %3\;" ++ "and\t%6, %0, %4\;" ++ "or\t%6, %6, %5\;" ++ "sc.w.rl\t%5, %6, %1\;" ++ "bnez\t%5, 1b"; ++ } ++ [(set (attr "length") (const_int 28))]) ++ ++(define_expand "atomic_fetch_nand" ++ [(match_operand:SHORT 0 "register_operand") ;; old value at mem ++ (not:SHORT (and:SHORT (match_operand:SHORT 1 "memory_operand") ;; mem location ++ (match_operand:SHORT 2 "reg_or_0_operand"))) ;; value for op ++ (match_operand:SI 3 "const_int_operand")] ;; model ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ /* We have no QImode/HImode atomics, so form a mask, then use ++ subword_atomic_fetch_strong_nand to implement a LR/SC version of the ++ operation. */ ++ ++ /* Logic duplicated in gcc/libgcc/config/riscv/atomic.c for use when inlining ++ is disabled */ ++ ++ rtx old = gen_reg_rtx (SImode); ++ rtx mem = operands[1]; ++ rtx value = operands[2]; ++ rtx aligned_mem = gen_reg_rtx (SImode); ++ rtx shift = gen_reg_rtx (SImode); ++ rtx mask = gen_reg_rtx (SImode); ++ rtx not_mask = gen_reg_rtx (SImode); ++ ++ riscv_subword_address (mem, &aligned_mem, &shift, &mask, ¬_mask); ++ ++ rtx shifted_value = gen_reg_rtx (SImode); ++ riscv_lshift_subword (mode, value, shift, &shifted_value); ++ ++ emit_insn (gen_subword_atomic_fetch_strong_nand (old, aligned_mem, ++ shifted_value, ++ mask, not_mask)); ++ ++ emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old, ++ gen_lowpart (QImode, shift))); ++ ++ emit_move_insn (operands[0], gen_lowpart (mode, old)); ++ ++ DONE; ++}) ++ ++(define_insn "subword_atomic_fetch_strong_nand" ++ [(set (match_operand:SI 0 "register_operand" "=&r") ;; old value at mem ++ (match_operand:SI 1 "memory_operand" "+A")) ;; mem location ++ (set (match_dup 1) ++ (unspec_volatile:SI ++ [(not:SI (and:SI (match_dup 1) ++ (match_operand:SI 2 "register_operand" "rI"))) ;; value for op ++ (match_operand:SI 3 "register_operand" "rI")] ;; mask ++ UNSPEC_SYNC_OLD_OP_SUBWORD)) ++ (match_operand:SI 4 "register_operand" "rI") ;; not_mask ++ (clobber (match_scratch:SI 5 "=&r")) ;; tmp_1 ++ (clobber (match_scratch:SI 6 "=&r"))] ;; tmp_2 ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++ { ++ return "1:\;" ++ "lr.w.aq\t%0, %1\;" ++ "and\t%5, %0, %2\;" ++ "not\t%5, %5\;" ++ "and\t%5, %5, %3\;" ++ "and\t%6, %0, %4\;" ++ "or\t%6, %6, %5\;" ++ "sc.w.rl\t%5, %6, %1\;" ++ "bnez\t%5, 1b"; ++ } ++ [(set (attr "length") (const_int 32))]) ++ ++(define_expand "atomic_fetch_" ++ [(match_operand:SHORT 0 "register_operand") ;; old value at mem ++ (any_atomic:SHORT (match_operand:SHORT 1 "memory_operand") ;; mem location ++ (match_operand:SHORT 2 "reg_or_0_operand")) ;; value for op ++ (match_operand:SI 3 "const_int_operand")] ;; model ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ /* We have no QImode/HImode atomics, so form a mask, then use ++ subword_atomic_fetch_strong_ to implement a LR/SC version of the ++ operation. */ ++ ++ /* Logic duplicated in gcc/libgcc/config/riscv/atomic.c for use when inlining ++ is disabled */ ++ ++ rtx old = gen_reg_rtx (SImode); ++ rtx mem = operands[1]; ++ rtx value = operands[2]; ++ rtx aligned_mem = gen_reg_rtx (SImode); ++ rtx shift = gen_reg_rtx (SImode); ++ rtx mask = gen_reg_rtx (SImode); ++ rtx not_mask = gen_reg_rtx (SImode); ++ ++ riscv_subword_address (mem, &aligned_mem, &shift, &mask, ¬_mask); ++ ++ rtx shifted_value = gen_reg_rtx (SImode); ++ riscv_lshift_subword (mode, value, shift, &shifted_value); ++ ++ emit_insn (gen_subword_atomic_fetch_strong_ (old, aligned_mem, ++ shifted_value, ++ mask, not_mask)); ++ ++ emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old, ++ gen_lowpart (QImode, shift))); ++ ++ emit_move_insn (operands[0], gen_lowpart (mode, old)); ++ ++ DONE; ++}) ++ + (define_insn "atomic_exchange" + [(set (match_operand:GPR 0 "register_operand" "=&r") + (unspec_volatile:GPR +@@ -104,6 +236,56 @@ + [(set_attr "type" "atomic") + (set (attr "length") (const_int 8))]) + ++(define_expand "atomic_exchange" ++ [(match_operand:SHORT 0 "register_operand") ;; old value at mem ++ (match_operand:SHORT 1 "memory_operand") ;; mem location ++ (match_operand:SHORT 2 "register_operand") ;; value ++ (match_operand:SI 3 "const_int_operand")] ;; model ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ rtx old = gen_reg_rtx (SImode); ++ rtx mem = operands[1]; ++ rtx value = operands[2]; ++ rtx aligned_mem = gen_reg_rtx (SImode); ++ rtx shift = gen_reg_rtx (SImode); ++ rtx mask = gen_reg_rtx (SImode); ++ rtx not_mask = gen_reg_rtx (SImode); ++ ++ riscv_subword_address (mem, &aligned_mem, &shift, &mask, ¬_mask); ++ ++ rtx shifted_value = gen_reg_rtx (SImode); ++ riscv_lshift_subword (mode, value, shift, &shifted_value); ++ ++ emit_insn (gen_subword_atomic_exchange_strong (old, aligned_mem, ++ shifted_value, not_mask)); ++ ++ emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old, ++ gen_lowpart (QImode, shift))); ++ ++ emit_move_insn (operands[0], gen_lowpart (mode, old)); ++ DONE; ++}) ++ ++(define_insn "subword_atomic_exchange_strong" ++ [(set (match_operand:SI 0 "register_operand" "=&r") ;; old value at mem ++ (match_operand:SI 1 "memory_operand" "+A")) ;; mem location ++ (set (match_dup 1) ++ (unspec_volatile:SI ++ [(match_operand:SI 2 "reg_or_0_operand" "rI") ;; value ++ (match_operand:SI 3 "reg_or_0_operand" "rI")] ;; not_mask ++ UNSPEC_SYNC_EXCHANGE_SUBWORD)) ++ (clobber (match_scratch:SI 4 "=&r"))] ;; tmp_1 ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++ { ++ return "1:\;" ++ "lr.w.aq\t%0, %1\;" ++ "and\t%4, %0, %3\;" ++ "or\t%4, %4, %2\;" ++ "sc.w.rl\t%4, %4, %1\;" ++ "bnez\t%4, 1b"; ++ } ++ [(set (attr "length") (const_int 20))]) ++ + (define_insn "atomic_cas_value_strong" + [(set (match_operand:GPR 0 "register_operand" "=&r") + (match_operand:GPR 1 "memory_operand" "+A")) +@@ -153,6 +335,125 @@ + DONE; + }) + ++(define_expand "atomic_compare_and_swap" ++ [(match_operand:SI 0 "register_operand") ;; bool output ++ (match_operand:SHORT 1 "register_operand") ;; val output ++ (match_operand:SHORT 2 "memory_operand") ;; memory ++ (match_operand:SHORT 3 "reg_or_0_operand") ;; expected value ++ (match_operand:SHORT 4 "reg_or_0_operand") ;; desired value ++ (match_operand:SI 5 "const_int_operand") ;; is_weak ++ (match_operand:SI 6 "const_int_operand") ;; mod_s ++ (match_operand:SI 7 "const_int_operand")] ;; mod_f ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ emit_insn (gen_atomic_cas_value_strong (operands[1], operands[2], ++ operands[3], operands[4], ++ operands[6], operands[7])); ++ ++ rtx val = gen_reg_rtx (SImode); ++ if (operands[1] != const0_rtx) ++ emit_move_insn (val, gen_rtx_SIGN_EXTEND (SImode, operands[1])); ++ else ++ emit_move_insn (val, const0_rtx); ++ ++ rtx exp = gen_reg_rtx (SImode); ++ if (operands[3] != const0_rtx) ++ emit_move_insn (exp, gen_rtx_SIGN_EXTEND (SImode, operands[3])); ++ else ++ emit_move_insn (exp, const0_rtx); ++ ++ rtx compare = val; ++ if (exp != const0_rtx) ++ { ++ rtx difference = gen_rtx_MINUS (SImode, val, exp); ++ compare = gen_reg_rtx (SImode); ++ emit_move_insn (compare, difference); ++ } ++ ++ if (word_mode != SImode) ++ { ++ rtx reg = gen_reg_rtx (word_mode); ++ emit_move_insn (reg, gen_rtx_SIGN_EXTEND (word_mode, compare)); ++ compare = reg; ++ } ++ ++ emit_move_insn (operands[0], gen_rtx_EQ (SImode, compare, const0_rtx)); ++ DONE; ++}) ++ ++(define_expand "atomic_cas_value_strong" ++ [(match_operand:SHORT 0 "register_operand") ;; val output ++ (match_operand:SHORT 1 "memory_operand") ;; memory ++ (match_operand:SHORT 2 "reg_or_0_operand") ;; expected value ++ (match_operand:SHORT 3 "reg_or_0_operand") ;; desired value ++ (match_operand:SI 4 "const_int_operand") ;; mod_s ++ (match_operand:SI 5 "const_int_operand") ;; mod_f ++ (match_scratch:SHORT 6)] ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ /* We have no QImode/HImode atomics, so form a mask, then use ++ subword_atomic_cas_strong to implement a LR/SC version of the ++ operation. */ ++ ++ /* Logic duplicated in gcc/libgcc/config/riscv/atomic.c for use when inlining ++ is disabled */ ++ ++ rtx old = gen_reg_rtx (SImode); ++ rtx mem = operands[1]; ++ rtx aligned_mem = gen_reg_rtx (SImode); ++ rtx shift = gen_reg_rtx (SImode); ++ rtx mask = gen_reg_rtx (SImode); ++ rtx not_mask = gen_reg_rtx (SImode); ++ ++ riscv_subword_address (mem, &aligned_mem, &shift, &mask, ¬_mask); ++ ++ rtx o = operands[2]; ++ rtx n = operands[3]; ++ rtx shifted_o = gen_reg_rtx (SImode); ++ rtx shifted_n = gen_reg_rtx (SImode); ++ ++ riscv_lshift_subword (mode, o, shift, &shifted_o); ++ riscv_lshift_subword (mode, n, shift, &shifted_n); ++ ++ emit_move_insn (shifted_o, gen_rtx_AND (SImode, shifted_o, mask)); ++ emit_move_insn (shifted_n, gen_rtx_AND (SImode, shifted_n, mask)); ++ ++ emit_insn (gen_subword_atomic_cas_strong (old, aligned_mem, ++ shifted_o, shifted_n, ++ mask, not_mask)); ++ ++ emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old, ++ gen_lowpart (QImode, shift))); ++ ++ emit_move_insn (operands[0], gen_lowpart (mode, old)); ++ ++ DONE; ++}) ++ ++(define_insn "subword_atomic_cas_strong" ++ [(set (match_operand:SI 0 "register_operand" "=&r") ;; old value at mem ++ (match_operand:SI 1 "memory_operand" "+A")) ;; mem location ++ (set (match_dup 1) ++ (unspec_volatile:SI [(match_operand:SI 2 "reg_or_0_operand" "rJ") ;; expected value ++ (match_operand:SI 3 "reg_or_0_operand" "rJ")] ;; desired value ++ UNSPEC_COMPARE_AND_SWAP_SUBWORD)) ++ (match_operand:SI 4 "register_operand" "rI") ;; mask ++ (match_operand:SI 5 "register_operand" "rI") ;; not_mask ++ (clobber (match_scratch:SI 6 "=&r"))] ;; tmp_1 ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++ { ++ return "1:\;" ++ "lr.w.aq\t%0, %1\;" ++ "and\t%6, %0, %4\;" ++ "bne\t%6, %z2, 1f\;" ++ "and\t%6, %0, %5\;" ++ "or\t%6, %6, %3\;" ++ "sc.w.rl\t%6, %6, %1\;" ++ "bnez\t%6, 1b\;" ++ "1:"; ++ } ++ [(set (attr "length") (const_int 28))]) ++ + (define_expand "atomic_test_and_set" + [(match_operand:QI 0 "register_operand" "") ;; bool output + (match_operand:QI 1 "memory_operand" "+A") ;; memory +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -1226,7 +1226,8 @@ See RS/6000 and PowerPC Options. + -mbig-endian -mlittle-endian + -mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{reg} + -mstack-protector-guard-offset=@var{offset} +--mcsr-check -mno-csr-check} ++-mcsr-check -mno-csr-check ++-minline-atomics -mno-inline-atomics} + + @emph{RL78 Options} + @gccoptlist{-msim -mmul=none -mmul=g13 -mmul=g14 -mallregs +@@ -29006,6 +29007,13 @@ Do or don't use smaller but slower prolo + library function calls. The default is to use fast inline prologues and + epilogues. + ++@opindex minline-atomics ++@item -minline-atomics ++@itemx -mno-inline-atomics ++Do or don't use smaller but slower subword atomic emulation code that uses ++libatomic function calls. The default is to use fast inline subword atomics ++that do not require libatomic. ++ + @opindex mshorten-memrefs + @item -mshorten-memrefs + @itemx -mno-shorten-memrefs +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-1.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mno-inline-atomics" } */ ++/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "fetch_and_nand" { target *-*-* } 0 } */ ++/* { dg-final { scan-assembler "\tcall\t__sync_fetch_and_add_1" } } */ ++/* { dg-final { scan-assembler "\tcall\t__sync_fetch_and_nand_1" } } */ ++/* { dg-final { scan-assembler "\tcall\t__sync_bool_compare_and_swap_1" } } */ ++ ++char foo; ++char bar; ++char baz; ++ ++int ++main () ++{ ++ __sync_fetch_and_add(&foo, 1); ++ __sync_fetch_and_nand(&bar, 1); ++ __sync_bool_compare_and_swap (&baz, 1, 2); ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-2.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile } */ ++/* Verify that subword atomics do not generate calls. */ ++/* { dg-options "-minline-atomics" } */ ++/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "fetch_and_nand" { target *-*-* } 0 } */ ++/* { dg-final { scan-assembler-not "\tcall\t__sync_fetch_and_add_1" } } */ ++/* { dg-final { scan-assembler-not "\tcall\t__sync_fetch_and_nand_1" } } */ ++/* { dg-final { scan-assembler-not "\tcall\t__sync_bool_compare_and_swap_1" } } */ ++ ++#include "inline-atomics-1.c" +\ No newline at end of file +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-3.c +@@ -0,0 +1,569 @@ ++/* Check all char alignments. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-op-1.c */ ++/* Test __atomic routines for existence and proper execution on 1 byte ++ values with each valid memory model. */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics -Wno-address-of-packed-member" } */ ++ ++/* Test the execution of the __atomic_*OP builtin routines for a char. */ ++ ++extern void abort(void); ++ ++char count, res; ++const char init = ~0; ++ ++struct A ++{ ++ char a; ++ char b; ++ char c; ++ char d; ++} __attribute__ ((packed)) A; ++ ++/* The fetch_op routines return the original value before the operation. */ ++ ++void ++test_fetch_add (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_CONSUME) != 1) ++ abort (); ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_ACQUIRE) != 2) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_RELEASE) != 3) ++ abort (); ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_ACQ_REL) != 4) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_SEQ_CST) != 5) ++ abort (); ++} ++ ++ ++void ++test_fetch_sub (char* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_RELAXED) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_CONSUME) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQUIRE) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_RELEASE) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQ_REL) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_SEQ_CST) != res--) ++ abort (); ++} ++ ++void ++test_fetch_and (char* v) ++{ ++ *v = init; ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, init, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_fetch_and (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_fetch_nand (char* v) ++{ ++ *v = init; ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_ACQUIRE) != 0 ) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL) != 0) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++void ++test_fetch_xor (char* v) ++{ ++ *v = init; ++ count = 0; ++ ++ if (__atomic_fetch_xor (v, count, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE) != 0) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++void ++test_fetch_or (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_fetch_or (v, count, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, 2, __ATOMIC_CONSUME) != 1) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_ACQUIRE) != 3) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, 8, __ATOMIC_RELEASE) != 7) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_ACQ_REL) != 15) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_SEQ_CST) != 31) ++ abort (); ++} ++ ++/* The OP_fetch routines return the new value after the operation. */ ++ ++void ++test_add_fetch (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_RELAXED) != 1) ++ abort (); ++ ++ if (__atomic_add_fetch (v, 1, __ATOMIC_CONSUME) != 2) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_ACQUIRE) != 3) ++ abort (); ++ ++ if (__atomic_add_fetch (v, 1, __ATOMIC_RELEASE) != 4) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_ACQ_REL) != 5) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_SEQ_CST) != 6) ++ abort (); ++} ++ ++ ++void ++test_sub_fetch (char* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, 1, __ATOMIC_CONSUME) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQUIRE) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, 1, __ATOMIC_RELEASE) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_SEQ_CST) != --res) ++ abort (); ++} ++ ++void ++test_and_fetch (char* v) ++{ ++ *v = init; ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ *v = init; ++ if (__atomic_and_fetch (v, init, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_and_fetch (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_and_fetch (v, 0, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_nand_fetch (char* v) ++{ ++ *v = init; ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_RELEASE) != 0) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++ ++ ++void ++test_xor_fetch (char* v) ++{ ++ *v = init; ++ count = 0; ++ ++ if (__atomic_xor_fetch (v, count, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_or_fetch (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_or_fetch (v, count, __ATOMIC_RELAXED) != 1) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, 2, __ATOMIC_CONSUME) != 3) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_ACQUIRE) != 7) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, 8, __ATOMIC_RELEASE) != 15) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_ACQ_REL) != 31) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_SEQ_CST) != 63) ++ abort (); ++} ++ ++ ++/* Test the OP routines with a result which isn't used. Use both variations ++ within each function. */ ++ ++void ++test_add (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ __atomic_add_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != 1) ++ abort (); ++ ++ __atomic_fetch_add (v, count, __ATOMIC_CONSUME); ++ if (*v != 2) ++ abort (); ++ ++ __atomic_add_fetch (v, 1 , __ATOMIC_ACQUIRE); ++ if (*v != 3) ++ abort (); ++ ++ __atomic_fetch_add (v, 1, __ATOMIC_RELEASE); ++ if (*v != 4) ++ abort (); ++ ++ __atomic_add_fetch (v, count, __ATOMIC_ACQ_REL); ++ if (*v != 5) ++ abort (); ++ ++ __atomic_fetch_add (v, count, __ATOMIC_SEQ_CST); ++ if (*v != 6) ++ abort (); ++} ++ ++ ++void ++test_sub (char* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ __atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, count + 1, __ATOMIC_CONSUME); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_sub_fetch (v, 1, __ATOMIC_ACQUIRE); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, 1, __ATOMIC_RELEASE); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, count + 1, __ATOMIC_SEQ_CST); ++ if (*v != --res) ++ abort (); ++} ++ ++void ++test_and (char* v) ++{ ++ *v = init; ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_RELAXED); ++ if (*v != 0) ++ abort (); ++ ++ *v = init; ++ __atomic_fetch_and (v, init, __ATOMIC_CONSUME); ++ if (*v != init) ++ abort (); ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != 0) ++ abort (); ++ ++ *v = ~*v; ++ __atomic_fetch_and (v, init, __ATOMIC_RELEASE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL); ++ if (*v != 0) ++ abort (); ++ ++ *v = ~*v; ++ __atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST); ++ if (*v != 0) ++ abort (); ++} ++ ++void ++test_nand (char* v) ++{ ++ *v = init; ++ ++ __atomic_fetch_nand (v, 0, __ATOMIC_RELAXED); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_nand (v, init, __ATOMIC_CONSUME); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_nand_fetch (v, init, __ATOMIC_RELEASE); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL); ++ if (*v != init) ++ abort (); ++ ++ __atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST); ++ if (*v != init) ++ abort (); ++} ++ ++ ++ ++void ++test_xor (char* v) ++{ ++ *v = init; ++ count = 0; ++ ++ __atomic_xor_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL); ++ if (*v != init) ++ abort (); ++ ++ __atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST); ++ if (*v != 0) ++ abort (); ++} ++ ++void ++test_or (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ __atomic_or_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != 1) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, count, __ATOMIC_CONSUME); ++ if (*v != 3) ++ abort (); ++ ++ count *= 2; ++ __atomic_or_fetch (v, 4, __ATOMIC_ACQUIRE); ++ if (*v != 7) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, 8, __ATOMIC_RELEASE); ++ if (*v != 15) ++ abort (); ++ ++ count *= 2; ++ __atomic_or_fetch (v, count, __ATOMIC_ACQ_REL); ++ if (*v != 31) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, count, __ATOMIC_SEQ_CST); ++ if (*v != 63) ++ abort (); ++} ++ ++int ++main () ++{ ++ char* V[] = {&A.a, &A.b, &A.c, &A.d}; ++ ++ for (int i = 0; i < 4; i++) { ++ test_fetch_add (V[i]); ++ test_fetch_sub (V[i]); ++ test_fetch_and (V[i]); ++ test_fetch_nand (V[i]); ++ test_fetch_xor (V[i]); ++ test_fetch_or (V[i]); ++ ++ test_add_fetch (V[i]); ++ test_sub_fetch (V[i]); ++ test_and_fetch (V[i]); ++ test_nand_fetch (V[i]); ++ test_xor_fetch (V[i]); ++ test_or_fetch (V[i]); ++ ++ test_add (V[i]); ++ test_sub (V[i]); ++ test_and (V[i]); ++ test_nand (V[i]); ++ test_xor (V[i]); ++ test_or (V[i]); ++ } ++ ++ return 0; ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-4.c +@@ -0,0 +1,566 @@ ++/* Check all short alignments. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-op-2.c */ ++/* Test __atomic routines for existence and proper execution on 2 byte ++ values with each valid memory model. */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics -Wno-address-of-packed-member" } */ ++ ++/* Test the execution of the __atomic_*OP builtin routines for a short. */ ++ ++extern void abort(void); ++ ++short count, res; ++const short init = ~0; ++ ++struct A ++{ ++ short a; ++ short b; ++} __attribute__ ((packed)) A; ++ ++/* The fetch_op routines return the original value before the operation. */ ++ ++void ++test_fetch_add (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_CONSUME) != 1) ++ abort (); ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_ACQUIRE) != 2) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_RELEASE) != 3) ++ abort (); ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_ACQ_REL) != 4) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_SEQ_CST) != 5) ++ abort (); ++} ++ ++ ++void ++test_fetch_sub (short* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_RELAXED) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_CONSUME) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQUIRE) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_RELEASE) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQ_REL) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_SEQ_CST) != res--) ++ abort (); ++} ++ ++void ++test_fetch_and (short* v) ++{ ++ *v = init; ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, init, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_fetch_and (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_fetch_nand (short* v) ++{ ++ *v = init; ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_ACQUIRE) != 0 ) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL) != 0) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++void ++test_fetch_xor (short* v) ++{ ++ *v = init; ++ count = 0; ++ ++ if (__atomic_fetch_xor (v, count, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE) != 0) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++void ++test_fetch_or (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_fetch_or (v, count, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, 2, __ATOMIC_CONSUME) != 1) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_ACQUIRE) != 3) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, 8, __ATOMIC_RELEASE) != 7) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_ACQ_REL) != 15) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_SEQ_CST) != 31) ++ abort (); ++} ++ ++/* The OP_fetch routines return the new value after the operation. */ ++ ++void ++test_add_fetch (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_RELAXED) != 1) ++ abort (); ++ ++ if (__atomic_add_fetch (v, 1, __ATOMIC_CONSUME) != 2) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_ACQUIRE) != 3) ++ abort (); ++ ++ if (__atomic_add_fetch (v, 1, __ATOMIC_RELEASE) != 4) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_ACQ_REL) != 5) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_SEQ_CST) != 6) ++ abort (); ++} ++ ++ ++void ++test_sub_fetch (short* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, 1, __ATOMIC_CONSUME) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQUIRE) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, 1, __ATOMIC_RELEASE) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_SEQ_CST) != --res) ++ abort (); ++} ++ ++void ++test_and_fetch (short* v) ++{ ++ *v = init; ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ *v = init; ++ if (__atomic_and_fetch (v, init, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_and_fetch (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_and_fetch (v, 0, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_nand_fetch (short* v) ++{ ++ *v = init; ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_RELEASE) != 0) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++ ++ ++void ++test_xor_fetch (short* v) ++{ ++ *v = init; ++ count = 0; ++ ++ if (__atomic_xor_fetch (v, count, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_or_fetch (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_or_fetch (v, count, __ATOMIC_RELAXED) != 1) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, 2, __ATOMIC_CONSUME) != 3) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_ACQUIRE) != 7) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, 8, __ATOMIC_RELEASE) != 15) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_ACQ_REL) != 31) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_SEQ_CST) != 63) ++ abort (); ++} ++ ++ ++/* Test the OP routines with a result which isn't used. Use both variations ++ within each function. */ ++ ++void ++test_add (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ __atomic_add_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != 1) ++ abort (); ++ ++ __atomic_fetch_add (v, count, __ATOMIC_CONSUME); ++ if (*v != 2) ++ abort (); ++ ++ __atomic_add_fetch (v, 1 , __ATOMIC_ACQUIRE); ++ if (*v != 3) ++ abort (); ++ ++ __atomic_fetch_add (v, 1, __ATOMIC_RELEASE); ++ if (*v != 4) ++ abort (); ++ ++ __atomic_add_fetch (v, count, __ATOMIC_ACQ_REL); ++ if (*v != 5) ++ abort (); ++ ++ __atomic_fetch_add (v, count, __ATOMIC_SEQ_CST); ++ if (*v != 6) ++ abort (); ++} ++ ++ ++void ++test_sub (short* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ __atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, count + 1, __ATOMIC_CONSUME); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_sub_fetch (v, 1, __ATOMIC_ACQUIRE); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, 1, __ATOMIC_RELEASE); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, count + 1, __ATOMIC_SEQ_CST); ++ if (*v != --res) ++ abort (); ++} ++ ++void ++test_and (short* v) ++{ ++ *v = init; ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_RELAXED); ++ if (*v != 0) ++ abort (); ++ ++ *v = init; ++ __atomic_fetch_and (v, init, __ATOMIC_CONSUME); ++ if (*v != init) ++ abort (); ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != 0) ++ abort (); ++ ++ *v = ~*v; ++ __atomic_fetch_and (v, init, __ATOMIC_RELEASE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL); ++ if (*v != 0) ++ abort (); ++ ++ *v = ~*v; ++ __atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST); ++ if (*v != 0) ++ abort (); ++} ++ ++void ++test_nand (short* v) ++{ ++ *v = init; ++ ++ __atomic_fetch_nand (v, 0, __ATOMIC_RELAXED); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_nand (v, init, __ATOMIC_CONSUME); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_nand_fetch (v, init, __ATOMIC_RELEASE); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL); ++ if (*v != init) ++ abort (); ++ ++ __atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST); ++ if (*v != init) ++ abort (); ++} ++ ++ ++ ++void ++test_xor (short* v) ++{ ++ *v = init; ++ count = 0; ++ ++ __atomic_xor_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL); ++ if (*v != init) ++ abort (); ++ ++ __atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST); ++ if (*v != 0) ++ abort (); ++} ++ ++void ++test_or (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ __atomic_or_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != 1) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, count, __ATOMIC_CONSUME); ++ if (*v != 3) ++ abort (); ++ ++ count *= 2; ++ __atomic_or_fetch (v, 4, __ATOMIC_ACQUIRE); ++ if (*v != 7) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, 8, __ATOMIC_RELEASE); ++ if (*v != 15) ++ abort (); ++ ++ count *= 2; ++ __atomic_or_fetch (v, count, __ATOMIC_ACQ_REL); ++ if (*v != 31) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, count, __ATOMIC_SEQ_CST); ++ if (*v != 63) ++ abort (); ++} ++ ++int ++main () { ++ short* V[] = {&A.a, &A.b}; ++ ++ for (int i = 0; i < 2; i++) { ++ test_fetch_add (V[i]); ++ test_fetch_sub (V[i]); ++ test_fetch_and (V[i]); ++ test_fetch_nand (V[i]); ++ test_fetch_xor (V[i]); ++ test_fetch_or (V[i]); ++ ++ test_add_fetch (V[i]); ++ test_sub_fetch (V[i]); ++ test_and_fetch (V[i]); ++ test_nand_fetch (V[i]); ++ test_xor_fetch (V[i]); ++ test_or_fetch (V[i]); ++ ++ test_add (V[i]); ++ test_sub (V[i]); ++ test_and (V[i]); ++ test_nand (V[i]); ++ test_xor (V[i]); ++ test_or (V[i]); ++ } ++ ++ return 0; ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-5.c +@@ -0,0 +1,87 @@ ++/* Test __atomic routines for existence and proper execution on 1 byte ++ values with each valid memory model. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-compare-exchange-1.c */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics" } */ ++ ++/* Test the execution of the __atomic_compare_exchange_n builtin for a char. */ ++ ++extern void abort(void); ++ ++char v = 0; ++char expected = 0; ++char max = ~0; ++char desired = ~0; ++char zero = 0; ++ ++#define STRONG 0 ++#define WEAK 1 ++ ++int ++main () ++{ ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != max) ++ abort (); ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != max) ++ abort (); ++ if (v != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ if (v != max) ++ abort (); ++ ++ /* Now test the generic version. */ ++ ++ v = 0; ++ ++ if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != max) ++ abort (); ++ ++ if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != max) ++ abort (); ++ if (v != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ if (v != max) ++ abort (); ++ ++ return 0; ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-6.c +@@ -0,0 +1,87 @@ ++/* Test __atomic routines for existence and proper execution on 2 byte ++ values with each valid memory model. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-compare-exchange-2.c */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics" } */ ++ ++/* Test the execution of the __atomic_compare_exchange_n builtin for a short. */ ++ ++extern void abort(void); ++ ++short v = 0; ++short expected = 0; ++short max = ~0; ++short desired = ~0; ++short zero = 0; ++ ++#define STRONG 0 ++#define WEAK 1 ++ ++int ++main () ++{ ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != max) ++ abort (); ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != max) ++ abort (); ++ if (v != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ if (v != max) ++ abort (); ++ ++ /* Now test the generic version. */ ++ ++ v = 0; ++ ++ if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != max) ++ abort (); ++ ++ if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != max) ++ abort (); ++ if (v != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ if (v != max) ++ abort (); ++ ++ return 0; ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-7.c +@@ -0,0 +1,69 @@ ++/* Test __atomic routines for existence and proper execution on 1 byte ++ values with each valid memory model. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-exchange-1.c */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics" } */ ++ ++/* Test the execution of the __atomic_exchange_n builtin for a char. */ ++ ++extern void abort(void); ++ ++char v, count, ret; ++ ++int ++main () ++{ ++ v = 0; ++ count = 0; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELAXED) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQUIRE) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELEASE) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQ_REL) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_SEQ_CST) != count) ++ abort (); ++ count++; ++ ++ /* Now test the generic version. */ ++ ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_RELAXED); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQUIRE); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_RELEASE); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQ_REL); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_SEQ_CST); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ return 0; ++} +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-8.c +@@ -0,0 +1,69 @@ ++/* Test __atomic routines for existence and proper execution on 2 byte ++ values with each valid memory model. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-exchange-2.c */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics" } */ ++ ++/* Test the execution of the __atomic_X builtin for a short. */ ++ ++extern void abort(void); ++ ++short v, count, ret; ++ ++int ++main () ++{ ++ v = 0; ++ count = 0; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELAXED) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQUIRE) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELEASE) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQ_REL) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_SEQ_CST) != count) ++ abort (); ++ count++; ++ ++ /* Now test the generic version. */ ++ ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_RELAXED); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQUIRE); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_RELEASE); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQ_REL); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_SEQ_CST); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ return 0; ++} +--- a/libgcc/config/riscv/atomic.c ++++ b/libgcc/config/riscv/atomic.c +@@ -30,6 +30,8 @@ see the files COPYING3 and COPYING.RUNTI + #define INVERT "not %[tmp1], %[tmp1]\n\t" + #define DONT_INVERT "" + ++/* Logic duplicated in gcc/gcc/config/riscv/sync.md for use when inlining is enabled */ ++ + #define GENERATE_FETCH_AND_OP(type, size, opname, insn, invert, cop) \ + type __sync_fetch_and_ ## opname ## _ ## size (type *p, type v) \ + { \ diff --git a/toolchain/gcc/patches-13.x/701-riscv-linux-Don-t-add-latomic-with-pthread.patch b/toolchain/gcc/patches-13.x/701-riscv-linux-Don-t-add-latomic-with-pthread.patch new file mode 100644 index 00000000000..328c7be9ce8 --- /dev/null +++ b/toolchain/gcc/patches-13.x/701-riscv-linux-Don-t-add-latomic-with-pthread.patch @@ -0,0 +1,36 @@ +From 203f3060dd363361b172f7295f42bb6bf5ac0b3b Mon Sep 17 00:00:00 2001 +From: Andreas Schwab +Date: Sat, 23 Apr 2022 15:48:42 +0200 +Subject: [PATCH] riscv/linux: Don't add -latomic with -pthread + +Now that we have support for inline subword atomic operations, it is no +longer necessary to link against libatomic. This also fixes testsuite +failures because the framework does not properly set up the linker flags +for finding libatomic. +The use of atomic operations is also independent of the use of libpthread. + +gcc/ + * config/riscv/linux.h (LIB_SPEC): Don't redefine. +--- + gcc/config/riscv/linux.h | 10 ---------- + 1 file changed, 10 deletions(-) + +--- a/gcc/config/riscv/linux.h ++++ b/gcc/config/riscv/linux.h +@@ -35,16 +35,6 @@ along with GCC; see the file COPYING3. + #undef MUSL_DYNAMIC_LINKER + #define MUSL_DYNAMIC_LINKER "/lib/ld-musl-riscv" XLEN_SPEC MUSL_ABI_SUFFIX ".so.1" + +-/* Because RISC-V only has word-sized atomics, it requries libatomic where +- others do not. So link libatomic by default, as needed. */ +-#undef LIB_SPEC +-#ifdef LD_AS_NEEDED_OPTION +-#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC \ +- " %{pthread:" LD_AS_NEEDED_OPTION " -latomic " LD_NO_AS_NEEDED_OPTION "}" +-#else +-#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC " -latomic " +-#endif +- + #define ICACHE_FLUSH_FUNC "__riscv_flush_icache" + + #define CPP_SPEC "%{pthread:-D_REENTRANT}" diff --git a/toolchain/gcc/patches-13.x/910-mbsd_multi.patch b/toolchain/gcc/patches-13.x/910-mbsd_multi.patch index 095fc62f69e..8af05c99946 100644 --- a/toolchain/gcc/patches-13.x/910-mbsd_multi.patch +++ b/toolchain/gcc/patches-13.x/910-mbsd_multi.patch @@ -114,7 +114,7 @@ Date: Tue Jul 31 00:52:27 2007 +0000 ; On SVR4 targets, it also controls whether or not to emit a --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi -@@ -10061,6 +10061,17 @@ This option is only supported for C and +@@ -10062,6 +10062,17 @@ This option is only supported for C and @option{-Wall} and by @option{-Wpedantic}, which can be disabled with @option{-Wno-pointer-sign}.