Merge Official Source
This commit is contained in:
commit
8e1125c340
2
Makefile
2
Makefile
@ -14,7 +14,7 @@ $(if $(findstring $(space),$(TOPDIR)),$(error ERROR: The path to the OpenWrt dir
|
||||
|
||||
world:
|
||||
|
||||
DISTRO_PKG_CONFIG:=$(shell command -pv pkg-config | grep -E '\/usr' | head -n 1)
|
||||
DISTRO_PKG_CONFIG:=$(shell which -a pkg-config | grep -E '\/usr' | head -n 1)
|
||||
export PATH:=$(TOPDIR)/staging_dir/host/bin:$(PATH)
|
||||
|
||||
ifneq ($(OPENWRT_BUILD),1)
|
||||
|
@ -2,4 +2,8 @@ src-git packages https://github.com/immortalwrt/packages.git
|
||||
src-git luci https://github.com/immortalwrt/luci.git
|
||||
src-git routing https://github.com/openwrt-routing/packages.git
|
||||
src-git telephony https://github.com/openwrt/telephony.git
|
||||
src-git freifunk https://github.com/freifunk/openwrt-packages.git
|
||||
#src-git video https://github.com/openwrt/video.git
|
||||
#src-git targets https://github.com/openwrt/targets.git
|
||||
#src-git management https://github.com/openwrt-management/packages.git
|
||||
#src-git oldpackages http://git.openwrt.org/packages.git
|
||||
#src-link custom /usr/src/openwrt/custom-feed
|
||||
|
@ -15,7 +15,7 @@ MAKE_PATH = $(firstword $(CMAKE_BINARY_SUBDIR) .)
|
||||
ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),)
|
||||
cmake_tool=$(TOOLCHAIN_DIR)/bin/$(1)
|
||||
else
|
||||
cmake_tool=$(shell command -v $(1))
|
||||
cmake_tool=$(shell which $(1))
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CCACHE),)
|
||||
|
@ -214,7 +214,7 @@ define Build/fit
|
||||
-i $(KERNEL_BUILD_DIR)/initrd.cpio$(strip $(call Build/initrd_compression)))) \
|
||||
-a $(KERNEL_LOADADDR) -e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \
|
||||
$(if $(DEVICE_FDT_NUM),-n $(DEVICE_FDT_NUM)) \
|
||||
-c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config@1") \
|
||||
-c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config-1") \
|
||||
-A $(LINUX_KARCH) -v $(LINUX_VERSION)
|
||||
PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage $(if $(findstring external,$(word 3,$(1))),\
|
||||
-E -B 0x1000 $(if $(findstring static,$(word 3,$(1))),-p 0x1000)) -f $@.its $@.new
|
||||
|
@ -139,7 +139,7 @@ endef
|
||||
define Image/BuildKernel/MkFIT
|
||||
$(TOPDIR)/scripts/mkits.sh \
|
||||
-D $(1) -o $(KDIR)/fit-$(1).its -k $(2) $(if $(3),-d $(3)) -C $(4) -a $(5) -e $(6) \
|
||||
-c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config@1") \
|
||||
-c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config-1") \
|
||||
-A $(LINUX_KARCH) -v $(LINUX_VERSION)
|
||||
PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage -f $(KDIR)/fit-$(1).its $(KDIR)/fit-$(1)$(7).itb
|
||||
endef
|
||||
@ -301,7 +301,7 @@ endif
|
||||
|
||||
ifdef CONFIG_TARGET_ROOTFS_CPIOGZ
|
||||
define Image/Build/cpiogz
|
||||
( cd $(TARGET_DIR); find . | $(STAGING_DIR_HOST)/bin/cpio -o -H newc -R root:root | gzip -9n >$(BIN_DIR)/$(IMG_ROOTFS).cpio.gz )
|
||||
( cd $(TARGET_DIR); find . | $(STAGING_DIR_HOST)/bin/cpio -o -H newc -R 0:0 | gzip -9n >$(BIN_DIR)/$(IMG_ROOTFS).cpio.gz )
|
||||
endef
|
||||
endif
|
||||
|
||||
|
@ -163,7 +163,7 @@ ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS_SEPARATE),y)
|
||||
ifeq ($(CONFIG_EXTERNAL_CPIO),y)
|
||||
$(CP) $(CONFIG_EXTERNAL_CPIO) $(KERNEL_BUILD_DIR)/initrd.cpio
|
||||
else
|
||||
( cd $(TARGET_DIR); find . | $(STAGING_DIR_HOST)/bin/cpio -o -H newc -R root:root > $(KERNEL_BUILD_DIR)/initrd.cpio )
|
||||
( cd $(TARGET_DIR); find . | $(STAGING_DIR_HOST)/bin/cpio -o -H newc -R 0:0 > $(KERNEL_BUILD_DIR)/initrd.cpio )
|
||||
endif
|
||||
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_BZIP2),bzip2 -9 -c < $(KERNEL_BUILD_DIR)/initrd.cpio > $(KERNEL_BUILD_DIR)/initrd.cpio.bzip2)
|
||||
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_GZIP),gzip -f -S .gzip -9n $(KERNEL_BUILD_DIR)/initrd.cpio)
|
||||
|
@ -6,11 +6,11 @@ ifdef CONFIG_TESTING_KERNEL
|
||||
KERNEL_PATCHVER:=$(KERNEL_TESTING_PATCHVER)
|
||||
endif
|
||||
|
||||
LINUX_VERSION-5.4 = .101
|
||||
LINUX_VERSION-5.10 = .18
|
||||
LINUX_VERSION-5.4 = .102
|
||||
LINUX_VERSION-5.10 = .20
|
||||
|
||||
LINUX_KERNEL_HASH-5.4.101 = 4e118c072dbe3209ddeaff32ecc558f7e809d54e661550342079f1ee76d9349d
|
||||
LINUX_KERNEL_HASH-5.10.18 = 3bc1ee2b1bf73b5ba936721953f3f9599fd165cef906cd5163c68d23cb9bb611
|
||||
LINUX_KERNEL_HASH-5.4.102 = fd697ce1c3f6024d4ae77d4eb5a1552199407b60cb8e90bc621e23cbce639aed
|
||||
LINUX_KERNEL_HASH-5.10.20 = 9be37146feba42be05137cf900a7d9012990b5a1d5e59bc0c8da1f86952930a3
|
||||
|
||||
remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1))))
|
||||
sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1)))))))
|
||||
|
@ -25,21 +25,21 @@ $(eval $(call TestHostCommand,proper-umask, \
|
||||
|
||||
ifndef IB
|
||||
$(eval $(call SetupHostCommand,gcc, \
|
||||
Please install the GNU C Compiler (gcc) 4.8 or later, \
|
||||
$(CC) -dumpversion | grep -E '^(4\.[8-9]|[5-9]\.?|10\.?)', \
|
||||
gcc -dumpversion | grep -E '^(4\.[8-9]|[5-9]\.?|10\.?)', \
|
||||
Please install the GNU C Compiler (gcc) 6 or later, \
|
||||
$(CC) -dumpversion | grep -E '^([6-9]\.?|1[0-9]\.?)', \
|
||||
gcc -dumpversion | grep -E '^([6-9]\.?|1[0-9]\.?)', \
|
||||
gcc --version | grep -E 'Apple.(LLVM|clang)' ))
|
||||
|
||||
$(eval $(call TestHostCommand,working-gcc, \
|
||||
\nPlease reinstall the GNU C Compiler (4.8 or later) - \
|
||||
\nPlease reinstall the GNU C Compiler (6 or later) - \
|
||||
it appears to be broken, \
|
||||
echo 'int main(int argc, char **argv) { return 0; }' | \
|
||||
gcc -x c -o $(TMP_DIR)/a.out -))
|
||||
|
||||
$(eval $(call SetupHostCommand,g++, \
|
||||
Please install the GNU C++ Compiler (g++) 4.8 or later, \
|
||||
$(CXX) -dumpversion | grep -E '^(4\.[8-9]|[5-9]\.?|10\.?)', \
|
||||
g++ -dumpversion | grep -E '^(4\.[8-9]|[5-9]\.?|10\.?)', \
|
||||
Please install the GNU C++ Compiler (g++) 6 or later, \
|
||||
$(CXX) -dumpversion | grep -E '^([6-9]\.?|1[0-9]\.?)', \
|
||||
g++ -dumpversion | grep -E '^([6-9]\.?|1[0-9]\.?)', \
|
||||
g++ --version | grep -E 'Apple.(LLVM|clang)' ))
|
||||
|
||||
$(eval $(call TestHostCommand,working-g++, \
|
||||
@ -166,6 +166,9 @@ $(eval $(call SetupHostCommand,file,Please install the 'file' package, \
|
||||
$(eval $(call SetupHostCommand,rsync,Please install 'rsync', \
|
||||
rsync --version </dev/null))
|
||||
|
||||
$(eval $(call SetupHostCommand,which,Please install 'which', \
|
||||
which which | grep which))
|
||||
|
||||
$(STAGING_DIR_HOST)/bin/mkhash: $(SCRIPT_DIR)/mkhash.c
|
||||
mkdir -p $(dir $@)
|
||||
$(CC) -O2 -I$(TOPDIR)/tools/include -o $@ $<
|
||||
|
@ -49,7 +49,7 @@ endef
|
||||
|
||||
define RequireCommand
|
||||
define Require/$(1)
|
||||
command -pv $(1)
|
||||
which $(1)
|
||||
endef
|
||||
|
||||
$$(eval $$(call Require,$(1),$(2)))
|
||||
@ -103,7 +103,7 @@ define SetupHostCommand
|
||||
$(call QuoteHostCommand,$(11)) $(call QuoteHostCommand,$(12)); do \
|
||||
if [ -n "$$$$$$$$cmd" ]; then \
|
||||
bin="$$$$$$$$(PATH="$(subst $(space),:,$(filter-out $(STAGING_DIR_HOST)/%,$(subst :,$(space),$(PATH))))" \
|
||||
command -pv "$$$$$$$${cmd%% *}")"; \
|
||||
which "$$$$$$$${cmd%% *}")"; \
|
||||
if [ -x "$$$$$$$$bin" ] && eval "$$$$$$$$cmd" >/dev/null 2>/dev/null; then \
|
||||
mkdir -p "$(STAGING_DIR_HOST)/bin"; \
|
||||
ln -sf "$$$$$$$$bin" "$(STAGING_DIR_HOST)/bin/$(strip $(1))"; \
|
||||
|
@ -31,10 +31,11 @@ load_led() {
|
||||
config_get gpio $1 gpio "0"
|
||||
config_get inverted $1 inverted "0"
|
||||
|
||||
if [ "$trigger" = "rssi" ]; then
|
||||
# handled by rssileds userspace process
|
||||
return
|
||||
fi
|
||||
# execute application led trigger
|
||||
[ -f "/usr/libexec/led-trigger/${trigger}" ] && {
|
||||
. "/usr/libexec/led-trigger/${trigger}"
|
||||
return 0
|
||||
}
|
||||
|
||||
[ "$trigger" = "usbdev" ] && {
|
||||
# Backward compatibility: translate to the new trigger
|
||||
|
@ -13,129 +13,88 @@ PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=https://github.com/mtk-openwrt/arm-trusted-firmware.git
|
||||
PKG_SOURCE_DATE:=2020-11-09
|
||||
PKG_SOURCE_VERSION:=03017334ccd8c0fac12e7db36749b95b9a7d745f
|
||||
PKG_MIRROR_HASH:=b211b2f9143d4debc7ad8dc959cb606888af20af790855dd66c87e451b6a1bc7
|
||||
PKG_SOURCE_DATE:=2021-02-25
|
||||
PKG_SOURCE_VERSION:=1220acb044a9db9a201aba3be0bb4ce0c9ed3702
|
||||
PKG_MIRROR_HASH:=f2ca44b9b8acfbd3a6be30aba316c765f73bad6231a821f524c9f21a845e50a3
|
||||
|
||||
PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
PKG_LICENSE_FILES:=LICENCE.mediatek
|
||||
|
||||
BLOBS_TARBALL:=tfa-mtk-files-for-2020-11-09.tgz
|
||||
BROMIMAGE_EXEC:=bromimage-x64
|
||||
|
||||
include $(INCLUDE_DIR)/trusted-firmware-a.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
PKG_LICENSE+=proprietary
|
||||
|
||||
define Download/tfa-files
|
||||
URL:=@OPENWRT
|
||||
URL_FILE:=$(BLOBS_TARBALL)
|
||||
FILE:=$(BLOBS_TARBALL)
|
||||
HASH:=689b097e4531d3eeca0c477675ab3dc3cace6ba4ed8a339116a9ede6537839d7
|
||||
endef
|
||||
|
||||
define Trusted-Firmware-A/Default
|
||||
BUILD_TARGET:=mediatek
|
||||
BUILD_SUBTARGET:=mt7622
|
||||
PLAT:=mt7622
|
||||
TFA_IMAGE:=bl2.img bl31.bin
|
||||
BOOT_DEVICE:=
|
||||
DDR_BLOB:=
|
||||
DDR3_FLYBY:=
|
||||
endef
|
||||
|
||||
define Trusted-Firmware-A/mt7622-nor-1ddr
|
||||
NAME:=MediaTek MT7622 (SPI-NOR, 1x DDR3)
|
||||
BOOT_DEVICE:=nor
|
||||
DDR_BLOB:=1
|
||||
endef
|
||||
|
||||
define Trusted-Firmware-A/mt7622-nor-2ddr
|
||||
NAME:=MediaTek MT7622 (SPI-NOR, 2x DDR3)
|
||||
BOOT_DEVICE:=nor
|
||||
DDR_BLOB:=2
|
||||
DDR3_FLYBY:=1
|
||||
endef
|
||||
|
||||
define Trusted-Firmware-A/mt7622-snand-1ddr
|
||||
NAME:=MediaTek MT7622 (SPI-NAND, 1x DDR3)
|
||||
BOOT_DEVICE:=snand
|
||||
DDR_BLOB:=1
|
||||
endef
|
||||
|
||||
define Trusted-Firmware-A/mt7622-snand-2ddr
|
||||
NAME:=MediaTek MT7622 (SPI-SNAND, 2x DDR3)
|
||||
BOOT_DEVICE:=snand
|
||||
DDR_BLOB:=2
|
||||
DDR3_FLYBY:=1
|
||||
endef
|
||||
|
||||
define Trusted-Firmware-A/mt7622-emmc-1ddr
|
||||
NAME:=MediaTek MT7622 (eMMC, 1x DDR3)
|
||||
BOOT_DEVICE:=emmc
|
||||
DDR_BLOB:=1
|
||||
endef
|
||||
|
||||
define Trusted-Firmware-A/mt7622-emmc-2ddr
|
||||
NAME:=MediaTek MT7622 (eMMC, 2x DDR3)
|
||||
BOOT_DEVICE:=emmc
|
||||
DDR_BLOB:=2
|
||||
DDR3_FLYBY:=1
|
||||
endef
|
||||
|
||||
define Trusted-Firmware-A/mt7622-sdmmc-1ddr
|
||||
NAME:=MediaTek MT7622 (SDcard, 1x DDR3)
|
||||
BOOT_DEVICE:=sdmmc
|
||||
DDR_BLOB:=1
|
||||
endef
|
||||
|
||||
define Trusted-Firmware-A/mt7622-sdmmc-2ddr
|
||||
NAME:=MediaTek MT7622 (SDcard, 2x DDR3)
|
||||
BOOT_DEVICE:=sdmmc
|
||||
DDR_BLOB:=2
|
||||
DDR3_FLYBY:=1
|
||||
endef
|
||||
|
||||
TFA_TARGETS:= \
|
||||
mt7622-nor-1ddr \
|
||||
mt7622-nor-2ddr \
|
||||
mt7622-snand-1ddr \
|
||||
mt7622-snand-2ddr \
|
||||
mt7622-emmc-1ddr \
|
||||
mt7622-emmc-2ddr \
|
||||
mt7622-sdmmc-1ddr \
|
||||
mt7622-sdmmc-2ddr
|
||||
mt7622-nor-1ddr \
|
||||
mt7622-nor-2ddr \
|
||||
mt7622-snand-1ddr \
|
||||
mt7622-snand-2ddr \
|
||||
mt7622-emmc-1ddr \
|
||||
mt7622-emmc-2ddr \
|
||||
mt7622-sdmmc-1ddr \
|
||||
mt7622-sdmmc-2ddr
|
||||
|
||||
TFA_MAKE_FLAGS += BOOT_DEVICE=$(BOOT_DEVICE) all
|
||||
|
||||
define Build/Prepare
|
||||
$(call Build/Prepare/Default)
|
||||
$(eval $(call Download,tfa-files))
|
||||
# replace 'bromimage' tool by static version
|
||||
$(TAR) -vxzf $(DL_DIR)/$(BLOBS_TARBALL) --wildcards \
|
||||
-O "*/$(BROMIMAGE_EXEC)" > $(PKG_BUILD_DIR)/tools/mediatek/bromimage/bromimage
|
||||
$(TAR) -vxzf $(DL_DIR)/$(BLOBS_TARBALL) --wildcards \
|
||||
-C $(PKG_BUILD_DIR) \
|
||||
--strip-components=1 */LICENCE.mediatek
|
||||
endef
|
||||
TFA_MAKE_FLAGS += BOOT_DEVICE=$(BOOT_DEVICE) $(if $(DDR3_FLYBY),DDR3_FLYBY=1) all
|
||||
|
||||
define Build/Configure
|
||||
$(call Build/Configure/Default)
|
||||
# replace DRAM calib blobs if needed (variant '2' is shipped upstream)
|
||||
ifeq ($(DDR_BLOB),1)
|
||||
$(TAR) -vxzf $(DL_DIR)/$(BLOBS_TARBALL) --wildcards \
|
||||
-C $(PKG_BUILD_DIR)/plat/mediatek/mt7622/drivers/dram/release \
|
||||
--strip-components=1 */*.o
|
||||
endif
|
||||
endef
|
||||
|
||||
define Package/trusted-firmware-a/install
|
||||
$(INSTALL_DIR) $(STAGING_DIR_IMAGE)
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/build/mt7622/release/bl2.img $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-bl2.img
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/build/mt7622/release/bl31.bin $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-bl31.bin
|
||||
ifeq ($(BOOT_DEVICE),emmc)
|
||||
$(INSTALL_DATA) $(DL_DIR)/mt7622-header_emmc.bin $(STAGING_DIR_IMAGE)/
|
||||
endif
|
||||
ifeq ($(BOOT_DEVICE),sdmmc)
|
||||
$(INSTALL_DATA) $(DL_DIR)/mt7622-header_sdmmc.bin $(STAGING_DIR_IMAGE)/
|
||||
endif
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage/Trusted-Firmware-A))
|
||||
|
@ -0,0 +1,17 @@
|
||||
Index: arm-trusted-firmware-mediatek-2021-02-25-1220acb0/plat/mediatek/mt7622/platform.mk
|
||||
===================================================================
|
||||
--- arm-trusted-firmware-mediatek-2021-02-25-1220acb0.orig/plat/mediatek/mt7622/platform.mk
|
||||
+++ arm-trusted-firmware-mediatek-2021-02-25-1220acb0/plat/mediatek/mt7622/platform.mk
|
||||
@@ -99,9 +99,9 @@ BL2_SOURCES += drivers/mmc/mmc.c \
|
||||
BROM_HEADER_TYPE := sdmmc
|
||||
CPPFLAGS += -DMSDC_INDEX=1
|
||||
DEVICE_HEADER_OFFSET ?= 0x80000
|
||||
-ifeq ($(BROM_SIGN_KEY),)
|
||||
-$(error BootROM signing key is required for SD booting. Please specify BROM_SIGN_KEY)
|
||||
-endif
|
||||
+#ifeq ($(BROM_SIGN_KEY),)
|
||||
+#$(error BootROM signing key is required for SD booting. Please specify BROM_SIGN_KEY)
|
||||
+#endif
|
||||
endif
|
||||
ifeq ($(BOOT_DEVICE),snand)
|
||||
include ${MTK_PLAT}/common/drivers/snfi/mtk-snand.mk
|
@ -1,24 +0,0 @@
|
||||
--- a/plat/mediatek/common/drivers/nandx/core/nand/device_spi.c
|
||||
+++ b/plat/mediatek/common/drivers/nandx/core/nand/device_spi.c
|
||||
@@ -150,6 +150,21 @@ static struct device_spi spi_nand[] = {
|
||||
&spi_extend_cmds, 0xff, 0xff
|
||||
},
|
||||
{
|
||||
+ NAND_DEVICE("FM35X1GA",
|
||||
+ NAND_PACK_ID(0xe5, 0x71, 0, 0, 0, 0, 0, 0),
|
||||
+ 2, 0, 3, 3,
|
||||
+ 1, 1, 1, 1024, KB(128), KB(2), 64, 1,
|
||||
+ &spi_cmds, &spi_addressing, &spi_status[0],
|
||||
+ &spi_endurance, &spi_array_timing),
|
||||
+ {
|
||||
+ NAND_SPI_PROTECT(0xa0, 1, 2, 6),
|
||||
+ NAND_SPI_CONFIG(0xb0, 4, 6, 1),
|
||||
+ NAND_SPI_STATUS(0xc0, 4, 5),
|
||||
+ NAND_SPI_CHARACTER(0xff, 0xff, 0xff, 0xff)
|
||||
+ },
|
||||
+ &spi_extend_cmds, 0xff, 0xff
|
||||
+ },
|
||||
+ {
|
||||
NAND_DEVICE("NO-DEVICE",
|
||||
NAND_PACK_ID(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 1,
|
@ -1,6 +1,14 @@
|
||||
--- a/arch/arm/dts/mt7622-bananapi-bpi-r64.dts
|
||||
+++ b/arch/arm/dts/mt7622-bananapi-bpi-r64.dts
|
||||
@@ -27,6 +27,42 @@
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
aliases {
|
||||
spi0 = &snfi;
|
||||
+ ethernet0 = ð
|
||||
};
|
||||
|
||||
memory@40000000 {
|
||||
@@ -27,6 +29,42 @@
|
||||
reg = <0x40000000 0x40000000>;
|
||||
};
|
||||
|
||||
@ -43,7 +51,7 @@
|
||||
reg_1p8v: regulator-1p8v {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "fixed-1.8V";
|
||||
@@ -139,11 +163,12 @@
|
||||
@@ -139,11 +177,12 @@
|
||||
|
||||
};
|
||||
|
||||
@ -58,7 +66,7 @@
|
||||
/* "I2S2_OUT, "I2S4_IN"", "I2S3_IN", "I2S2_IN",
|
||||
* "I2S4_OUT", "I2S3_OUT" are used as DAT0, DAT1,
|
||||
* DAT2, DAT3, CMD, CLK for SD respectively.
|
||||
@@ -164,7 +189,6 @@
|
||||
@@ -164,7 +203,6 @@
|
||||
pins = "TXD3";
|
||||
bias-pull-up;
|
||||
};
|
||||
@ -66,7 +74,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
@@ -199,7 +223,7 @@
|
||||
@@ -199,7 +237,7 @@
|
||||
status = "okay";
|
||||
bus-width = <8>;
|
||||
max-frequency = <50000000>;
|
||||
@ -75,7 +83,7 @@
|
||||
vmmc-supply = <®_3p3v>;
|
||||
vqmmc-supply = <®_3p3v>;
|
||||
non-removable;
|
||||
@@ -207,14 +231,15 @@
|
||||
@@ -207,14 +245,15 @@
|
||||
|
||||
&mmc1 {
|
||||
pinctrl-names = "default";
|
||||
|
@ -164,7 +164,7 @@
|
||||
+emmc_write_hdr=mmc dev 0 0 && mmc erase 0x0 0x40 && mmc write $loadaddr 0x0 0x40
|
||||
+emmc_write_bl3=mmc dev 0 0 && mmc erase 0x1000 0x800 && mmc write $loadaddr 0x1000 0x800
|
||||
+emmc_write_recovery=iminfo $loadaddr && mmc dev 0 && part start mmc 0 $part_recovery part_addr && part size mmc 0 $part_recovery part_size && run mmc_write_vol
|
||||
+emmc_init=run sdmmc_read_emmc_hdr && run emmc_write_hdr && run sdmmc_read_emmc_bl3 && run emmc_write_bl3 && run sdmmc_read_recovery && run emmc_write_recovery && run sdmmc_read_emmc_bl2 && run emmc_write_bl2 ; env default bootcmd ; saveenv ; saveenv
|
||||
+emmc_init=run sdmmc_read_emmc_bl2 && run emmc_write_bl2 && run sdmmc_read_emmc_hdr && run emmc_write_hdr && run sdmmc_read_emmc_bl3 && run emmc_write_bl3 && run sdmmc_read_recovery && run emmc_write_recovery ; env default bootcmd ; saveenv ; saveenv
|
||||
+sdmmc_write_production=iminfo $fileaddr && mmc dev 1 && part start mmc 1 $part_default part_addr && part size mmc 1 $part_default part_size && run mmc_write_vol
|
||||
+sdmmc_write_recovery=iminfo $fileaddr && mmc dev 1 && part start mmc 1 $part_recovery part_addr && part size mmc 1 $part_recovery part_size && run mmc_write_vol
|
||||
+sdmmc_read_production=mmc dev 1 && part start mmc 1 $part_default part_addr && part size mmc 1 $part_default part_size && run mmc_read_vol
|
||||
|
@ -2,13 +2,13 @@ include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=bcm63xx-cfe
|
||||
PKG_RELEASE:=1
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE_URL:=https://github.com/openwrt/bcm63xx-cfe.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_DATE:=2020-12-27
|
||||
PKG_SOURCE_VERSION:=c0b36917ea565c4ffac2e723f77c9d27d0691c33
|
||||
PKG_MIRROR_HASH:=75262534b1fbeba2299621ec3112d9d22b3e3de4cb73e8d7cac1e0b7e5eece77
|
||||
PKG_SOURCE_DATE:=2021-03-05
|
||||
PKG_SOURCE_VERSION:=d03501629fc8b1ba8f9b0961d543c256a3d0098f
|
||||
PKG_MIRROR_HASH:=b32a6f68d59c8f4534def7ec2568ad7da7a612a605b9406328309c78115ee88d
|
||||
|
||||
PKG_FLAGS:=nonshared
|
||||
|
||||
|
@ -1388,7 +1388,7 @@ define KernelPackage/usb-net-cdc-ncm
|
||||
KCONFIG:=CONFIG_USB_NET_CDC_NCM
|
||||
FILES:= $(LINUX_DIR)/drivers/$(USBNET_DIR)/cdc_ncm.ko
|
||||
AUTOLOAD:=$(call AutoProbe,cdc_ncm)
|
||||
$(call AddDepends/usb-net,+kmod-usb-net-cdc-ether)
|
||||
$(call AddDepends/usb-net,+!LINUX_5_4:kmod-usb-net-cdc-ether)
|
||||
endef
|
||||
|
||||
define KernelPackage/usb-net-cdc-ncm/description
|
||||
@ -1650,28 +1650,22 @@ endef
|
||||
|
||||
$(eval $(call KernelPackage,usbmon))
|
||||
|
||||
XHCI_MODULES := xhci-hcd xhci-pci xhci-plat-hcd
|
||||
ifdef CONFIG_TARGET_ramips_mt7621
|
||||
XHCI_MODULES += xhci-mtk
|
||||
endif
|
||||
XHCI_FILES := $(wildcard $(patsubst %,$(LINUX_DIR)/drivers/usb/host/%.ko,$(XHCI_MODULES)))
|
||||
XHCI_AUTOLOAD := $(patsubst $(LINUX_DIR)/drivers/usb/host/%.ko,%,$(XHCI_FILES))
|
||||
|
||||
define KernelPackage/usb3
|
||||
TITLE:=Support for USB3 controllers
|
||||
DEPENDS:= \
|
||||
+kmod-usb-xhci-hcd \
|
||||
+TARGET_bcm53xx:kmod-usb-bcma \
|
||||
+TARGET_bcm53xx:kmod-phy-bcm-ns-usb3
|
||||
+TARGET_bcm53xx:kmod-phy-bcm-ns-usb3 \
|
||||
+TARGET_ramips_mt7621:kmod-usb-xhci-mtk \
|
||||
+(TARGET_apm821xx_nand&&LINUX_5_10):kmod-usb-xhci-pci-renesas
|
||||
KCONFIG:= \
|
||||
CONFIG_USB_PCI=y \
|
||||
CONFIG_USB_XHCI_HCD \
|
||||
CONFIG_USB_XHCI_PCI \
|
||||
CONFIG_USB_XHCI_PLATFORM \
|
||||
CONFIG_USB_XHCI_MTK \
|
||||
CONFIG_USB_XHCI_HCD_DEBUGGING=n
|
||||
CONFIG_USB_XHCI_PLATFORM
|
||||
FILES:= \
|
||||
$(XHCI_FILES)
|
||||
AUTOLOAD:=$(call AutoLoad,54,$(XHCI_AUTOLOAD),1)
|
||||
$(LINUX_DIR)/drivers/usb/host/xhci-pci.ko \
|
||||
$(LINUX_DIR)/drivers/usb/host/xhci-plat-hcd.ko
|
||||
AUTOLOAD:=$(call AutoLoad,54,xhci-pci xhci-plat-hcd,1)
|
||||
$(call AddDepends/usb)
|
||||
endef
|
||||
|
||||
@ -1714,6 +1708,60 @@ endef
|
||||
$(eval $(call KernelPackage,usb-roles))
|
||||
|
||||
|
||||
define KernelPackage/usb-xhci-hcd
|
||||
TITLE:=xHCI HCD (USB 3.0) support
|
||||
KCONFIG:= \
|
||||
CONFIG_USB_XHCI_HCD \
|
||||
CONFIG_USB_XHCI_HCD_DEBUGGING=n
|
||||
HIDDEN:=1
|
||||
FILES:=$(LINUX_DIR)/drivers/usb/host/xhci-hcd.ko
|
||||
AUTOLOAD:=$(call AutoLoad,54,xhci-hcd,1)
|
||||
$(call AddDepends/usb)
|
||||
endef
|
||||
|
||||
define KernelPackage/usb-xhci-hcd/description
|
||||
The eXtensible Host Controller Interface (xHCI) is standard for USB 3.0
|
||||
"SuperSpeed" host controller hardware.
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,usb-xhci-hcd))
|
||||
|
||||
|
||||
define KernelPackage/usb-xhci-mtk
|
||||
TITLE:=xHCI support for MediaTek SoCs
|
||||
DEPENDS:=+kmod-usb-xhci-hcd
|
||||
KCONFIG:=CONFIG_USB_XHCI_MTK
|
||||
HIDDEN:=1
|
||||
FILES:=$(LINUX_DIR)/drivers/usb/host/xhci-mtk.ko
|
||||
AUTOLOAD:=$(call AutoLoad,54,xhci-mtk,1)
|
||||
$(call AddDepends/usb)
|
||||
endef
|
||||
|
||||
define KernelPackage/usb-xhci-mtk/description
|
||||
Kernel support for the xHCI host controller found in MediaTek SoCs.
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,usb-xhci-mtk))
|
||||
|
||||
|
||||
define KernelPackage/usb-xhci-pci-renesas
|
||||
TITLE:=Support for additional Renesas xHCI controller with firmware
|
||||
DEPENDS:=@LINUX_5_10
|
||||
KCONFIG:=CONFIG_USB_XHCI_PCI_RENESAS
|
||||
HIDDEN:=1
|
||||
FILES:=$(LINUX_DIR)/drivers/usb/host/xhci-pci-renesas.ko
|
||||
AUTOLOAD:=$(call AutoLoad,54,xhci-pci-renesas,1)
|
||||
$(call AddDepends/usb)
|
||||
endef
|
||||
|
||||
define KernelPackage/usb-xhci-pci-renesas/description
|
||||
Kernel support for the Renesas xHCI controller with firmware. Make sure you have
|
||||
the firwmare for the device and installed on your system for this device to work.
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,usb-xhci-pci-renesas))
|
||||
|
||||
|
||||
define KernelPackage/chaoskey
|
||||
SUBMENU:=$(USB_MENU)
|
||||
TITLE:=Chaoskey hardware RNG support
|
||||
|
@ -40,6 +40,8 @@ define Package/rssileds/install
|
||||
$(INSTALL_BIN) ./files/rssileds.init $(1)/etc/init.d/rssileds
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/rssileds $(1)/usr/sbin/
|
||||
$(INSTALL_DIR) $(1)/usr/libexec/led-trigger
|
||||
$(INSTALL_BIN) ./files/rssi $(1)/usr/libexec/led-trigger/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,rssileds))
|
||||
|
3
package/network/utils/rssileds/files/rssi
Normal file
3
package/network/utils/rssileds/files/rssi
Normal file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
logger -t led-trigger "LED trigger rssi is handled by /etc/init.d/rssileds"
|
@ -12,9 +12,9 @@ PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/fstools.git
|
||||
PKG_MIRROR_HASH:=d9b6a24bd8c03b89178141926db17240fe72f52af3d11f70baca352415c7214d
|
||||
PKG_SOURCE_DATE:=2021-03-02
|
||||
PKG_SOURCE_VERSION:=19d7d9313d9e868669ae6cb1bf9e840ba2461b41
|
||||
PKG_MIRROR_HASH:=5e55b446e3e171cd609d94fe00cf528fc5b784e9a4cb911730ba3ee9622e2e0b
|
||||
PKG_SOURCE_DATE:=2021-03-05
|
||||
PKG_SOURCE_VERSION:=3c38f0c889177dfac51fa7213c567a110709be71
|
||||
CMAKE_INSTALL:=1
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
@ -81,7 +81,7 @@ fi
|
||||
# Conditionally create fdt information
|
||||
if [ -n "${DTB}" ]; then
|
||||
FDT_NODE="
|
||||
fdt@$FDTNUM {
|
||||
fdt-$FDTNUM {
|
||||
description = \"${ARCH_UPPER} OpenWrt ${DEVICE} device tree blob\";
|
||||
${COMPATIBLE_PROP}
|
||||
data = /incbin/(\"${DTB}\");
|
||||
@ -96,12 +96,12 @@ if [ -n "${DTB}" ]; then
|
||||
};
|
||||
};
|
||||
"
|
||||
FDT_PROP="fdt = \"fdt@$FDTNUM\";"
|
||||
FDT_PROP="fdt = \"fdt-$FDTNUM\";"
|
||||
fi
|
||||
|
||||
if [ -n "${INITRD}" ]; then
|
||||
INITRD_NODE="
|
||||
initrd@$INITRDNUM {
|
||||
initrd-$INITRDNUM {
|
||||
description = \"${ARCH_UPPER} OpenWrt ${DEVICE} initrd\";
|
||||
${COMPATIBLE_PROP}
|
||||
data = /incbin/(\"${INITRD}\");
|
||||
@ -116,14 +116,14 @@ if [ -n "${INITRD}" ]; then
|
||||
};
|
||||
};
|
||||
"
|
||||
INITRD_PROP="ramdisk=\"initrd@${INITRDNUM}\";"
|
||||
INITRD_PROP="ramdisk=\"initrd-${INITRDNUM}\";"
|
||||
fi
|
||||
|
||||
|
||||
if [ -n "${ROOTFS}" ]; then
|
||||
dd if="${ROOTFS}" of="${ROOTFS}.pagesync" bs=4096 conv=sync
|
||||
ROOTFS_NODE="
|
||||
rootfs@$ROOTFSNUM {
|
||||
rootfs-$ROOTFSNUM {
|
||||
description = \"${ARCH_UPPER} OpenWrt ${DEVICE} rootfs\";
|
||||
${COMPATIBLE_PROP}
|
||||
data = /incbin/(\"${ROOTFS}.pagesync\");
|
||||
@ -138,7 +138,7 @@ if [ -n "${ROOTFS}" ]; then
|
||||
};
|
||||
};
|
||||
"
|
||||
LOADABLES="${LOADABLES:+$LOADABLES, }\"rootfs@${ROOTFSNUM}\""
|
||||
LOADABLES="${LOADABLES:+$LOADABLES, }\"rootfs-${ROOTFSNUM}\""
|
||||
fi
|
||||
|
||||
# Create a default, fully populated DTS file
|
||||
@ -149,7 +149,7 @@ DATA="/dts-v1/;
|
||||
#address-cells = <1>;
|
||||
|
||||
images {
|
||||
kernel@1 {
|
||||
kernel-1 {
|
||||
description = \"${ARCH_UPPER} OpenWrt Linux-${VERSION}\";
|
||||
data = /incbin/(\"${KERNEL}\");
|
||||
type = \"kernel\";
|
||||
@ -174,7 +174,7 @@ ${ROOTFS_NODE}
|
||||
default = \"${CONFIG}\";
|
||||
${CONFIG} {
|
||||
description = \"OpenWrt ${DEVICE}\";
|
||||
kernel = \"kernel@1\";
|
||||
kernel = \"kernel-1\";
|
||||
${FDT_PROP}
|
||||
${LOADABLES:+loadables = ${LOADABLES};}
|
||||
${COMPATIBLE_PROP}
|
||||
|
@ -10,6 +10,7 @@ FEATURES:=fpu dt gpio ramdisk squashfs usb
|
||||
SUBTARGETS:=nand sata
|
||||
|
||||
KERNEL_PATCHVER:=5.4
|
||||
KERNEL_TESTING_PATCHVER:=5.10
|
||||
|
||||
define Target/Description
|
||||
Build images for AppliedMicro APM821xx based boards.
|
||||
|
286
target/linux/apm821xx/config-5.10
Normal file
286
target/linux/apm821xx/config-5.10
Normal file
@ -0,0 +1,286 @@
|
||||
# CONFIG_40x is not set
|
||||
CONFIG_44x=y
|
||||
CONFIG_460EX=y
|
||||
CONFIG_4xx=y
|
||||
CONFIG_4xx_SOC=y
|
||||
# CONFIG_ADVANCED_OPTIONS is not set
|
||||
CONFIG_APM821xx=y
|
||||
CONFIG_APOLLO3G=y
|
||||
# CONFIG_ARCHES is not set
|
||||
CONFIG_ARCH_32BIT_OFF_T=y
|
||||
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
|
||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
CONFIG_ARCH_KEEP_MEMBLOCK=y
|
||||
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS=11
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MAX=17
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MIN=11
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
|
||||
CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_ARCH_WEAK_RELEASE_ACQUIRE=y
|
||||
CONFIG_AUDIT_ARCH=y
|
||||
# CONFIG_BAMBOO is not set
|
||||
# CONFIG_BLK_DEV_INITRD is not set
|
||||
CONFIG_BLK_MQ_PCI=y
|
||||
CONFIG_BLK_PM=y
|
||||
CONFIG_BLUESTONE=y
|
||||
CONFIG_BOOKE=y
|
||||
CONFIG_BOOKE_WDT=y
|
||||
# CONFIG_CANYONLANDS is not set
|
||||
CONFIG_CLKDEV_LOOKUP=y
|
||||
CONFIG_CLONE_BACKWARDS=y
|
||||
CONFIG_CMDLINE="rootfstype=squashfs noinitrd"
|
||||
CONFIG_CMDLINE_FROM_BOOTLOADER=y
|
||||
CONFIG_COMMON_CLK=y
|
||||
CONFIG_COMPAT_32BIT_TIME=y
|
||||
CONFIG_CPU_BIG_ENDIAN=y
|
||||
CONFIG_CRC16=y
|
||||
# CONFIG_CRC32_SARWATE is not set
|
||||
CONFIG_CRC32_SLICEBY8=y
|
||||
CONFIG_CRYPTO_ACOMP2=y
|
||||
CONFIG_CRYPTO_AEAD=y
|
||||
CONFIG_CRYPTO_AEAD2=y
|
||||
CONFIG_CRYPTO_AUTHENC=y
|
||||
CONFIG_CRYPTO_CCM=y
|
||||
CONFIG_CRYPTO_CFB=y
|
||||
CONFIG_CRYPTO_CTR=y
|
||||
CONFIG_CRYPTO_DEFLATE=y
|
||||
CONFIG_CRYPTO_DEV_PPC4XX=y
|
||||
CONFIG_CRYPTO_DRBG=y
|
||||
CONFIG_CRYPTO_DRBG_HMAC=y
|
||||
CONFIG_CRYPTO_DRBG_MENU=y
|
||||
CONFIG_CRYPTO_ECB=y
|
||||
CONFIG_CRYPTO_ESSIV=y
|
||||
CONFIG_CRYPTO_GCM=y
|
||||
CONFIG_CRYPTO_GF128MUL=y
|
||||
CONFIG_CRYPTO_GHASH=y
|
||||
CONFIG_CRYPTO_HASH=y
|
||||
CONFIG_CRYPTO_HASH2=y
|
||||
CONFIG_CRYPTO_HMAC=y
|
||||
CONFIG_CRYPTO_HW=y
|
||||
CONFIG_CRYPTO_JITTERENTROPY=y
|
||||
CONFIG_CRYPTO_LIB_SHA256=y
|
||||
CONFIG_CRYPTO_LZO=y
|
||||
CONFIG_CRYPTO_MANAGER=y
|
||||
CONFIG_CRYPTO_MANAGER2=y
|
||||
CONFIG_CRYPTO_MD5_PPC=y
|
||||
CONFIG_CRYPTO_NULL=y
|
||||
CONFIG_CRYPTO_NULL2=y
|
||||
CONFIG_CRYPTO_OFB=y
|
||||
CONFIG_CRYPTO_RNG=y
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
CONFIG_CRYPTO_RNG_DEFAULT=y
|
||||
CONFIG_CRYPTO_SEQIV=y
|
||||
CONFIG_CRYPTO_SHA1_PPC=y
|
||||
CONFIG_CRYPTO_SHA256=y
|
||||
CONFIG_DATA_SHIFT=12
|
||||
CONFIG_DEBUG_MISC=y
|
||||
CONFIG_DMA_DIRECT_REMAP=y
|
||||
CONFIG_DMA_REMAP=y
|
||||
CONFIG_DTC=y
|
||||
# CONFIG_E200 is not set
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
# CONFIG_EBONY is not set
|
||||
CONFIG_EDAC_ATOMIC_SCRUB=y
|
||||
CONFIG_EDAC_SUPPORT=y
|
||||
# CONFIG_EIGER is not set
|
||||
CONFIG_EXTRA_TARGETS="uImage"
|
||||
CONFIG_FIXED_PHY=y
|
||||
CONFIG_FORCE_PCI=y
|
||||
CONFIG_FREEZER=y
|
||||
# CONFIG_FSL_LBC is not set
|
||||
CONFIG_FW_CACHE=y
|
||||
CONFIG_FW_LOADER_PAGED_BUF=y
|
||||
CONFIG_GCC_PLUGINS=y
|
||||
# CONFIG_GCC_PLUGIN_CYC_COMPLEXITY is not set
|
||||
# CONFIG_GCC_PLUGIN_LATENT_ENTROPY is not set
|
||||
# CONFIG_GCC_PLUGIN_RANDSTRUCT is not set
|
||||
# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF is not set
|
||||
# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL is not set
|
||||
# CONFIG_GCC_PLUGIN_STRUCTLEAK_USER is not set
|
||||
CONFIG_GENERIC_ALLOCATOR=y
|
||||
CONFIG_GENERIC_ATOMIC64=y
|
||||
CONFIG_GENERIC_BUG=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||
CONFIG_GENERIC_CPU=y
|
||||
CONFIG_GENERIC_CPU_AUTOPROBE=y
|
||||
CONFIG_GENERIC_EARLY_IOREMAP=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
|
||||
CONFIG_GENERIC_ISA_DMA=y
|
||||
CONFIG_GENERIC_MSI_IRQ=y
|
||||
CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||
CONFIG_GENERIC_STRNCPY_FROM_USER=y
|
||||
CONFIG_GENERIC_STRNLEN_USER=y
|
||||
CONFIG_GENERIC_TIME_VSYSCALL=y
|
||||
# CONFIG_GEN_RTC is not set
|
||||
# CONFIG_GLACIER is not set
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIO_GENERIC=y
|
||||
CONFIG_GPIO_GENERIC_PLATFORM=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT_MAP=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
CONFIG_HW_RANDOM_PPC4XX=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_IBM_IIC=y
|
||||
CONFIG_IBM_EMAC=y
|
||||
CONFIG_IBM_EMAC_EMAC4=y
|
||||
CONFIG_IBM_EMAC_POLL_WEIGHT=32
|
||||
CONFIG_IBM_EMAC_RGMII=y
|
||||
CONFIG_IBM_EMAC_RXB=128
|
||||
CONFIG_IBM_EMAC_RX_COPY_THRESHOLD=256
|
||||
CONFIG_IBM_EMAC_TAH=y
|
||||
CONFIG_IBM_EMAC_TXB=128
|
||||
# CONFIG_ICON is not set
|
||||
CONFIG_ILLEGAL_POINTER_VALUE=0
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_DOMAIN_HIERARCHY=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_ISA_DMA_API=y
|
||||
# CONFIG_JFFS2_FS is not set
|
||||
# CONFIG_KATMAI is not set
|
||||
CONFIG_KERNEL_START=0xc0000000
|
||||
CONFIG_LEDS_TRIGGER_MTD=y
|
||||
CONFIG_LEDS_TRIGGER_PATTERN=y
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_LOCK_DEBUGGING_SUPPORT=y
|
||||
CONFIG_LOWMEM_SIZE=0x30000000
|
||||
CONFIG_LZO_COMPRESS=y
|
||||
CONFIG_LZO_DECOMPRESS=y
|
||||
# CONFIG_MATH_EMULATION is not set
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MEMFD_CREATE=y
|
||||
CONFIG_MIGRATION=y
|
||||
CONFIG_MMU_GATHER_PAGE_SIZE=y
|
||||
CONFIG_MODULES_USE_ELF_RELA=y
|
||||
CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y
|
||||
CONFIG_MTD_CFI_ADV_OPTIONS=y
|
||||
# CONFIG_MTD_CFI_GEOMETRY is not set
|
||||
# CONFIG_MTD_SPLIT_SQUASHFS_ROOT is not set
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEED_PER_CPU_KM=y
|
||||
CONFIG_NEED_SG_DMA_LENGTH=y
|
||||
CONFIG_NOT_COHERENT_CACHE=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_NO_HZ_COMMON=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_NR_IRQS=512
|
||||
CONFIG_NVMEM=y
|
||||
CONFIG_NVMEM_SYSFS=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_OF_MDIO=y
|
||||
CONFIG_OF_NET=y
|
||||
CONFIG_OLD_SIGACTION=y
|
||||
CONFIG_OLD_SIGSUSPEND=y
|
||||
CONFIG_PACKING=y
|
||||
CONFIG_PAGE_OFFSET=0xc0000000
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCIEAER=y
|
||||
CONFIG_PCIEPORTBUS=y
|
||||
CONFIG_PCIE_PME=y
|
||||
CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PCI_MSI=y
|
||||
CONFIG_PCI_MSI_ARCH_FALLBACKS=y
|
||||
CONFIG_PCI_MSI_IRQ_DOMAIN=y
|
||||
CONFIG_PGTABLE_LEVELS=2
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHYSICAL_START=0x00000000
|
||||
CONFIG_PHYS_64BIT=y
|
||||
CONFIG_PHYS_ADDR_T_64BIT=y
|
||||
CONFIG_PM=y
|
||||
# CONFIG_PMU_SYSFS is not set
|
||||
CONFIG_PM_AUTOSLEEP=y
|
||||
CONFIG_PM_CLK=y
|
||||
CONFIG_PM_SLEEP=y
|
||||
CONFIG_PM_WAKELOCKS=y
|
||||
CONFIG_PM_WAKELOCKS_GC=y
|
||||
CONFIG_PM_WAKELOCKS_LIMIT=100
|
||||
CONFIG_PPC=y
|
||||
CONFIG_PPC32=y
|
||||
CONFIG_PPC44x_SIMPLE=y
|
||||
CONFIG_PPC4xx_CPM=y
|
||||
CONFIG_PPC4xx_GPIO=y
|
||||
CONFIG_PPC4xx_MSI=y
|
||||
CONFIG_PPC4xx_PCI_EXPRESS=y
|
||||
# CONFIG_PPC64 is not set
|
||||
# CONFIG_PPC_47x is not set
|
||||
# CONFIG_PPC_85xx is not set
|
||||
# CONFIG_PPC_8xx is not set
|
||||
CONFIG_PPC_ADV_DEBUG_DACS=2
|
||||
CONFIG_PPC_ADV_DEBUG_DAC_RANGE=y
|
||||
CONFIG_PPC_ADV_DEBUG_DVCS=2
|
||||
CONFIG_PPC_ADV_DEBUG_IACS=4
|
||||
CONFIG_PPC_ADV_DEBUG_REGS=y
|
||||
# CONFIG_PPC_BOOK3S_6xx is not set
|
||||
CONFIG_PPC_DCR=y
|
||||
CONFIG_PPC_DCR_NATIVE=y
|
||||
# CONFIG_PPC_EARLY_DEBUG is not set
|
||||
CONFIG_PPC_FPU=y
|
||||
CONFIG_PPC_INDIRECT_PCI=y
|
||||
# CONFIG_PPC_IRQ_SOFT_MASK_DEBUG is not set
|
||||
CONFIG_PPC_MMU_NOHASH=y
|
||||
CONFIG_PPC_MMU_NOHASH_32=y
|
||||
CONFIG_PPC_MSI_BITMAP=y
|
||||
CONFIG_PPC_PAGE_SHIFT=12
|
||||
# CONFIG_PPC_PTDUMP is not set
|
||||
CONFIG_PPC_UDBG_16550=y
|
||||
CONFIG_PPC_WERROR=y
|
||||
CONFIG_PTE_64BIT=y
|
||||
# CONFIG_RAINIER is not set
|
||||
CONFIG_RAS=y
|
||||
CONFIG_RATIONAL=y
|
||||
CONFIG_RSEQ=y
|
||||
# CONFIG_SAM440EP is not set
|
||||
# CONFIG_SCOM_DEBUGFS is not set
|
||||
# CONFIG_SEQUOIA is not set
|
||||
CONFIG_SERIAL_8250_EXTENDED=y
|
||||
CONFIG_SERIAL_8250_FSL=y
|
||||
CONFIG_SERIAL_8250_SHARE_IRQ=y
|
||||
CONFIG_SERIAL_MCTRL_GPIO=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
CONFIG_SGL_ALLOC=y
|
||||
CONFIG_SPARSE_IRQ=y
|
||||
CONFIG_SRCU=y
|
||||
CONFIG_SUSPEND=y
|
||||
CONFIG_SUSPEND_FREEZER=y
|
||||
CONFIG_SWPHY=y
|
||||
CONFIG_SYSCTL_EXCEPTION_TRACE=y
|
||||
# CONFIG_TAISHAN is not set
|
||||
CONFIG_TASK_SIZE=0xc0000000
|
||||
CONFIG_THREAD_INFO_IN_TASK=y
|
||||
CONFIG_THREAD_SHIFT=13
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_TINY_SRCU=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_VDSO32=y
|
||||
# CONFIG_VIRTIO_MENU is not set
|
||||
# CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set
|
||||
# CONFIG_WARP is not set
|
||||
CONFIG_WATCHDOG_CORE=y
|
||||
# CONFIG_XILINX_SYSACE is not set
|
||||
CONFIG_XZ_DEC_BCJ=y
|
||||
CONFIG_XZ_DEC_POWERPC=y
|
||||
# CONFIG_YOSEMITE is not set
|
||||
CONFIG_ZLIB_DEFLATE=y
|
||||
CONFIG_ZLIB_INFLATE=y
|
@ -233,7 +233,7 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ndfc@1,0 {
|
||||
ndfc: ndfc@1,0 {
|
||||
compatible = "ibm,ndfc";
|
||||
reg = <00000003 00000000 00002000>;
|
||||
ccr = <0x00001000>;
|
||||
@ -241,6 +241,17 @@
|
||||
status = "disabled";
|
||||
|
||||
nand {
|
||||
/*
|
||||
* These are the same fixed "MAGIC" values
|
||||
* settings as in the drivers code.
|
||||
* They are the same for all devices that
|
||||
* have NAND.
|
||||
*/
|
||||
nand-ecc-engine = <&ndfc>;
|
||||
nand-ecc-algo = "hamming";
|
||||
nand-ecc-step-size = <256>;
|
||||
nand-ecc-strength = <1>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
};
|
||||
|
@ -47,6 +47,8 @@
|
||||
status = "okay";
|
||||
/* 32 MiB NAND Flash */
|
||||
nand {
|
||||
nand-is-boot-medium;
|
||||
|
||||
partition@0 {
|
||||
label = "u-boot";
|
||||
reg = <0x00000000 0x00150000>;
|
||||
|
@ -50,6 +50,8 @@
|
||||
ndfc@1,0 {
|
||||
status = "okay";
|
||||
nand {
|
||||
nand-is-boot-medium;
|
||||
|
||||
partition@0 {
|
||||
label = "u-boot";
|
||||
reg = <0x00000000 0x00100000>;
|
||||
|
@ -36,6 +36,8 @@
|
||||
status = "okay";
|
||||
/* 32 MiB SLC NAND Flash */
|
||||
nand {
|
||||
nand-is-boot-medium;
|
||||
|
||||
partition@0 {
|
||||
label = "u-boot";
|
||||
reg = <0x00000000 0x00100000>;
|
||||
|
@ -173,10 +173,13 @@
|
||||
};
|
||||
|
||||
&EBC0 {
|
||||
ndfc@1,0 {
|
||||
ndfc: ndfc@1,0 {
|
||||
|
||||
status = "okay";
|
||||
/* 128 MiB Nand Flash */
|
||||
nand {
|
||||
nand-is-boot-medium;
|
||||
|
||||
partition0,0@0 {
|
||||
label = "NAND 128MiB 3,3V 8-bit";
|
||||
reg = <0x00000000 0x08000000>;
|
||||
|
@ -0,0 +1,30 @@
|
||||
--- a/arch/powerpc/platforms/44x/Kconfig
|
||||
+++ b/arch/powerpc/platforms/44x/Kconfig
|
||||
@@ -121,6 +121,17 @@ config CANYONLANDS
|
||||
help
|
||||
This option enables support for the AMCC PPC460EX evaluation board.
|
||||
|
||||
+config APOLLO3G
|
||||
+ bool "Apollo3G"
|
||||
+ depends on 44x
|
||||
+ default n
|
||||
+ select PPC44x_SIMPLE
|
||||
+ select APM821xx
|
||||
+ select IBM_EMAC_RGMII
|
||||
+ select 460EX
|
||||
+ help
|
||||
+ This option enables support for the AMCC Apollo 3G board.
|
||||
+
|
||||
config GLACIER
|
||||
bool "Glacier"
|
||||
depends on 44x
|
||||
--- a/arch/powerpc/platforms/44x/ppc44x_simple.c
|
||||
+++ b/arch/powerpc/platforms/44x/ppc44x_simple.c
|
||||
@@ -47,6 +47,7 @@ machine_device_initcall(ppc44x_simple, p
|
||||
* board.c file for it rather than adding it to this list.
|
||||
*/
|
||||
static char *board[] __initdata = {
|
||||
+ "amcc,apollo3g",
|
||||
"amcc,arches",
|
||||
"amcc,bamboo",
|
||||
"apm,bluestone",
|
@ -0,0 +1,51 @@
|
||||
--- a/arch/powerpc/platforms/4xx/pci.c
|
||||
+++ b/arch/powerpc/platforms/4xx/pci.c
|
||||
@@ -1060,15 +1060,24 @@ static int __init apm821xx_pciex_init_po
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
- * Do a software reset on PCIe ports.
|
||||
- * This code is to fix the issue that pci drivers doesn't re-assign
|
||||
- * bus number for PCIE devices after Uboot
|
||||
- * scanned and configured all the buses (eg. PCIE NIC IntelPro/1000
|
||||
- * PT quad port, SAS LSI 1064E)
|
||||
+ * Only reset the PHY when no link is currently established.
|
||||
+ * This is for the Atheros PCIe board which has problems to establish
|
||||
+ * the link (again) after this PHY reset. All other currently tested
|
||||
+ * PCIe boards don't show this problem.
|
||||
*/
|
||||
-
|
||||
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x0);
|
||||
- mdelay(10);
|
||||
+ val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP);
|
||||
+ if (!(val & 0x00001000)) {
|
||||
+ /*
|
||||
+ * Do a software reset on PCIe ports.
|
||||
+ * This code is to fix the issue that pci drivers doesn't re-assign
|
||||
+ * bus number for PCIE devices after Uboot
|
||||
+ * scanned and configured all the buses (eg. PCIE NIC IntelPro/1000
|
||||
+ * PT quad port, SAS LSI 1064E)
|
||||
+ */
|
||||
+
|
||||
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x0);
|
||||
+ mdelay(10);
|
||||
+ }
|
||||
|
||||
if (port->endpoint)
|
||||
val = PTYPE_LEGACY_ENDPOINT << 20;
|
||||
@@ -1085,9 +1094,12 @@ static int __init apm821xx_pciex_init_po
|
||||
mtdcri(SDR0, PESDR0_460EX_L0DRV, 0x00000130);
|
||||
mtdcri(SDR0, PESDR0_460EX_L0CLK, 0x00000006);
|
||||
|
||||
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x10000000);
|
||||
- mdelay(50);
|
||||
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x30000000);
|
||||
+ val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP);
|
||||
+ if (!(val & 0x00001000)) {
|
||||
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x10000000);
|
||||
+ mdelay(50);
|
||||
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x30000000);
|
||||
+ }
|
||||
|
||||
mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET,
|
||||
mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) |
|
@ -0,0 +1,14 @@
|
||||
--- a/arch/powerpc/platforms/4xx/pci.c
|
||||
+++ b/arch/powerpc/platforms/4xx/pci.c
|
||||
@@ -1902,9 +1902,9 @@ static void __init ppc4xx_configure_pcie
|
||||
* if it works
|
||||
*/
|
||||
out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
|
||||
- out_le32(mbase + PECFG_PIM0LAH, 0x00000000);
|
||||
+ out_le32(mbase + PECFG_PIM0LAH, 0x00000008);
|
||||
out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
|
||||
- out_le32(mbase + PECFG_PIM1LAH, 0x00000000);
|
||||
+ out_le32(mbase + PECFG_PIM1LAH, 0x0000000c);
|
||||
out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
|
||||
out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
|
||||
|
@ -0,0 +1,53 @@
|
||||
From a0dc613140bab907a3d5787a7ae7b0638bf674d0 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Lamparter <chunkeey@gmail.com>
|
||||
Date: Thu, 23 Jun 2016 20:28:20 +0200
|
||||
Subject: [PATCH] usb: xhci: force MSI for uPD720201 and
|
||||
uPD720202
|
||||
|
||||
The APM82181 does not support MSI-X. When probed, it will
|
||||
produce a noisy warning.
|
||||
|
||||
---
|
||||
drivers/usb/host/pci-quirks.c | 362 ++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 362 insertions(+)
|
||||
|
||||
--- a/drivers/usb/host/xhci-pci.c
|
||||
+++ b/drivers/usb/host/xhci-pci.c
|
||||
@@ -260,6 +260,7 @@ static void xhci_pci_quirks(struct devic
|
||||
pdev->device == 0x0015) {
|
||||
xhci->quirks |= XHCI_RESET_ON_RESUME;
|
||||
xhci->quirks |= XHCI_ZERO_64B_REGS;
|
||||
+ xhci->quirks |= XHCI_FORCE_MSI;
|
||||
}
|
||||
if (pdev->vendor == PCI_VENDOR_ID_VIA)
|
||||
xhci->quirks |= XHCI_RESET_ON_RESUME;
|
||||
--- a/drivers/usb/host/xhci.c
|
||||
+++ b/drivers/usb/host/xhci.c
|
||||
@@ -423,10 +423,14 @@ static int xhci_try_enable_msi(struct us
|
||||
free_irq(hcd->irq, hcd);
|
||||
hcd->irq = 0;
|
||||
|
||||
- ret = xhci_setup_msix(xhci);
|
||||
- if (ret)
|
||||
- /* fall back to msi*/
|
||||
+ if (xhci->quirks & XHCI_FORCE_MSI) {
|
||||
ret = xhci_setup_msi(xhci);
|
||||
+ } else {
|
||||
+ ret = xhci_setup_msix(xhci);
|
||||
+ if (ret)
|
||||
+ /* fall back to msi*/
|
||||
+ ret = xhci_setup_msi(xhci);
|
||||
+ }
|
||||
|
||||
if (!ret) {
|
||||
hcd->msi_enabled = 1;
|
||||
--- a/drivers/usb/host/xhci.h
|
||||
+++ b/drivers/usb/host/xhci.h
|
||||
@@ -1886,6 +1886,7 @@ struct xhci_hcd {
|
||||
struct xhci_hub usb2_rhub;
|
||||
struct xhci_hub usb3_rhub;
|
||||
/* support xHCI 1.0 spec USB2 hardware LPM */
|
||||
+#define XHCI_FORCE_MSI (1 << 24)
|
||||
unsigned hw_lpm_support:1;
|
||||
/* Broken Suspend flag for SNPS Suspend resume issue */
|
||||
unsigned broken_suspend:1;
|
@ -0,0 +1,65 @@
|
||||
From 694f9bfb8efaef8a33e8992015ff9d0866faf4a2 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Lamparter <chunkeey@gmail.com>
|
||||
Date: Sun, 17 Dec 2017 17:27:15 +0100
|
||||
Subject: [PATCH 1/2] hwmon: tc654 add detection routine
|
||||
|
||||
This patch adds a detection routine for the TC654/TC655
|
||||
chips. Both IDs are listed in the Datasheet.
|
||||
|
||||
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
|
||||
---
|
||||
drivers/hwmon/tc654.c | 29 +++++++++++++++++++++++++++++
|
||||
1 file changed, 29 insertions(+)
|
||||
|
||||
--- a/drivers/hwmon/tc654.c
|
||||
+++ b/drivers/hwmon/tc654.c
|
||||
@@ -55,6 +55,11 @@ enum tc654_regs {
|
||||
/* Register data is read (and cached) at most once per second. */
|
||||
#define TC654_UPDATE_INTERVAL HZ
|
||||
|
||||
+/* Manufacturer and Version Identification Register Values */
|
||||
+#define TC654_MFR_ID_MICROCHIP 0x84
|
||||
+#define TC654_VER_ID 0x00
|
||||
+#define TC655_VER_ID 0x01
|
||||
+
|
||||
struct tc654_data {
|
||||
struct i2c_client *client;
|
||||
|
||||
@@ -481,6 +486,29 @@ static const struct i2c_device_id tc654_
|
||||
{}
|
||||
};
|
||||
|
||||
+static int
|
||||
+tc654_detect(struct i2c_client *new_client, struct i2c_board_info *info)
|
||||
+{
|
||||
+ struct i2c_adapter *adapter = new_client->adapter;
|
||||
+ int manufacturer, product;
|
||||
+
|
||||
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ manufacturer = i2c_smbus_read_byte_data(new_client, TC654_REG_MFR_ID);
|
||||
+ if (manufacturer != TC654_MFR_ID_MICROCHIP)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ product = i2c_smbus_read_byte_data(new_client, TC654_REG_VER_ID);
|
||||
+ if (!((product == TC654_VER_ID) || (product == TC655_VER_ID)))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ strlcpy(info->type, product == TC654_VER_ID ? "tc654" : "tc655",
|
||||
+ I2C_NAME_SIZE);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
MODULE_DEVICE_TABLE(i2c, tc654_id);
|
||||
|
||||
static struct i2c_driver tc654_driver = {
|
||||
@@ -489,6 +517,7 @@ static struct i2c_driver tc654_driver =
|
||||
},
|
||||
.probe_new = tc654_probe,
|
||||
.id_table = tc654_id,
|
||||
+ .detect = tc654_detect,
|
||||
};
|
||||
|
||||
module_i2c_driver(tc654_driver);
|
@ -0,0 +1,174 @@
|
||||
From 9cb27801b5cbad2e1aaf45aac428cb2fac5e1372 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Lamparter <chunkeey@gmail.com>
|
||||
Date: Sun, 17 Dec 2017 17:29:13 +0100
|
||||
Subject: [PATCH] hwmon: tc654: add thermal_cooling device
|
||||
|
||||
This patch adds a thermaL_cooling device to the tc654 driver.
|
||||
This allows the chip to be used for DT-based cooling.
|
||||
|
||||
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
|
||||
---
|
||||
drivers/hwmon/tc654.c | 103 +++++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 86 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/drivers/hwmon/tc654.c
|
||||
+++ b/drivers/hwmon/tc654.c
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
+#include <linux/thermal.h>
|
||||
#include <linux/util_macros.h>
|
||||
|
||||
enum tc654_regs {
|
||||
@@ -132,6 +133,9 @@ struct tc654_data {
|
||||
* writable register used to control the duty
|
||||
* cycle of the V OUT output.
|
||||
*/
|
||||
+
|
||||
+ /* optional cooling device */
|
||||
+ struct thermal_cooling_device *cdev;
|
||||
};
|
||||
|
||||
/* helper to grab and cache data, at most one time per second */
|
||||
@@ -367,36 +371,30 @@ static ssize_t pwm_mode_store(struct dev
|
||||
static const int tc654_pwm_map[16] = { 77, 88, 102, 112, 124, 136, 148, 160,
|
||||
172, 184, 196, 207, 219, 231, 243, 255};
|
||||
|
||||
+static int get_pwm(struct tc654_data *data)
|
||||
+{
|
||||
+ if (data->config & TC654_REG_CONFIG_SDM)
|
||||
+ return 0;
|
||||
+ else
|
||||
+ return tc654_pwm_map[data->duty_cycle];
|
||||
+}
|
||||
+
|
||||
static ssize_t pwm_show(struct device *dev, struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct tc654_data *data = tc654_update_client(dev);
|
||||
- int pwm;
|
||||
|
||||
if (IS_ERR(data))
|
||||
return PTR_ERR(data);
|
||||
|
||||
- if (data->config & TC654_REG_CONFIG_SDM)
|
||||
- pwm = 0;
|
||||
- else
|
||||
- pwm = tc654_pwm_map[data->duty_cycle];
|
||||
-
|
||||
- return sprintf(buf, "%d\n", pwm);
|
||||
+ return sprintf(buf, "%d\n", get_pwm(data));
|
||||
}
|
||||
|
||||
-static ssize_t pwm_store(struct device *dev, struct device_attribute *da,
|
||||
- const char *buf, size_t count)
|
||||
+static int _set_pwm(struct tc654_data *data, unsigned long val)
|
||||
{
|
||||
- struct tc654_data *data = dev_get_drvdata(dev);
|
||||
struct i2c_client *client = data->client;
|
||||
- unsigned long val;
|
||||
int ret;
|
||||
|
||||
- if (kstrtoul(buf, 10, &val))
|
||||
- return -EINVAL;
|
||||
- if (val > 255)
|
||||
- return -EINVAL;
|
||||
-
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
if (val == 0)
|
||||
@@ -416,6 +414,22 @@ static ssize_t pwm_store(struct device *
|
||||
|
||||
out:
|
||||
mutex_unlock(&data->update_lock);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static ssize_t pwm_store(struct device *dev, struct device_attribute *da,
|
||||
+ const char *buf, size_t count)
|
||||
+{
|
||||
+ struct tc654_data *data = dev_get_drvdata(dev);
|
||||
+ unsigned long val;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (kstrtoul(buf, 10, &val))
|
||||
+ return -EINVAL;
|
||||
+ if (val > 255)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ret = _set_pwm(data, val);
|
||||
return ret < 0 ? ret : count;
|
||||
}
|
||||
|
||||
@@ -447,6 +461,47 @@ static struct attribute *tc654_attrs[] =
|
||||
|
||||
ATTRIBUTE_GROUPS(tc654);
|
||||
|
||||
+/* cooling device */
|
||||
+
|
||||
+static int tc654_get_max_state(struct thermal_cooling_device *cdev,
|
||||
+ unsigned long *state)
|
||||
+{
|
||||
+ *state = 255;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int tc654_get_cur_state(struct thermal_cooling_device *cdev,
|
||||
+ unsigned long *state)
|
||||
+{
|
||||
+ struct tc654_data *data = tc654_update_client(cdev->devdata);
|
||||
+
|
||||
+ if (IS_ERR(data))
|
||||
+ return PTR_ERR(data);
|
||||
+
|
||||
+ *state = get_pwm(data);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int tc654_set_cur_state(struct thermal_cooling_device *cdev,
|
||||
+ unsigned long state)
|
||||
+{
|
||||
+ struct tc654_data *data = tc654_update_client(cdev->devdata);
|
||||
+
|
||||
+ if (IS_ERR(data))
|
||||
+ return PTR_ERR(data);
|
||||
+
|
||||
+ if (state > 255)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return _set_pwm(data, state);
|
||||
+}
|
||||
+
|
||||
+static const struct thermal_cooling_device_ops tc654_fan_cool_ops = {
|
||||
+ .get_max_state = tc654_get_max_state,
|
||||
+ .get_cur_state = tc654_get_cur_state,
|
||||
+ .set_cur_state = tc654_set_cur_state,
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* device probe and removal
|
||||
*/
|
||||
@@ -477,7 +532,21 @@ static int tc654_probe(struct i2c_client
|
||||
hwmon_dev =
|
||||
devm_hwmon_device_register_with_groups(dev, client->name, data,
|
||||
tc654_groups);
|
||||
- return PTR_ERR_OR_ZERO(hwmon_dev);
|
||||
+ if (IS_ERR(hwmon_dev))
|
||||
+ return PTR_ERR(hwmon_dev);
|
||||
+
|
||||
+#if IS_ENABLED(CONFIG_OF)
|
||||
+ /* Optional cooling device register for Device tree platforms */
|
||||
+ data->cdev = thermal_of_cooling_device_register(client->dev.of_node,
|
||||
+ "tc654", hwmon_dev,
|
||||
+ &tc654_fan_cool_ops);
|
||||
+#else /* CONFIG_OF */
|
||||
+ /* Optional cooling device register for non Device tree platforms */
|
||||
+ data->cdev = thermal_cooling_device_register("tc654", hwmon_dev,
|
||||
+ &tc654_fan_cool_ops);
|
||||
+#endif /* CONFIG_OF */
|
||||
+
|
||||
+ return PTR_ERR_OR_ZERO(data->cdev);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id tc654_id[] = {
|
@ -0,0 +1,29 @@
|
||||
From c9395ad54e2cabb87d408becc37566f3d8248933 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Lamparter <chunkeey@gmail.com>
|
||||
Date: Sun, 1 Dec 2019 02:08:23 +0100
|
||||
Subject: [PATCH] powerpc: bootwrapper: force gzip as mkimage's compression
|
||||
method
|
||||
|
||||
Due to CONFIG_KERNEL_XZ symbol, the bootwrapper code tries to
|
||||
instruct the mkimage to use the xz compression, which isn't
|
||||
supported. This patch forces the gzip compression, which is
|
||||
supported and doesn't matter because the generated uImage for
|
||||
the apm821xx target gets ignored as the OpenWrt toolchain will
|
||||
do separate U-Boot kernel images for each device individually.
|
||||
|
||||
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
|
||||
---
|
||||
arch/powerpc/boot/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/powerpc/boot/Makefile
|
||||
+++ b/arch/powerpc/boot/Makefile
|
||||
@@ -250,7 +250,7 @@ compressor-$(CONFIG_KERNEL_LZO) := lzo
|
||||
|
||||
# args (to if_changed): 1 = (this rule), 2 = platform, 3 = dts 4=dtb 5=initrd
|
||||
quiet_cmd_wrap = WRAP $@
|
||||
- cmd_wrap =$(CONFIG_SHELL) $(wrapper) -Z $(compressor-y) -c -o $@ -p $2 \
|
||||
+ cmd_wrap =$(CONFIG_SHELL) $(wrapper) -Z gzip -c -o $@ -p $2 \
|
||||
$(CROSSWRAP) $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) \
|
||||
vmlinux
|
||||
|
@ -8,6 +8,7 @@ CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MAX=15
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_AT803X_PHY=y
|
||||
CONFIG_ATH79=y
|
||||
CONFIG_ATH79_WDT=y
|
||||
CONFIG_BLK_MQ_PCI=y
|
||||
|
@ -1,31 +0,0 @@
|
||||
Upstream commit d40f0b6f2e21 ("spi: Avoid settingthe chip select if
|
||||
we don't need to") causes the SPI CS only to be asserted once and not
|
||||
if it's state stays the same.
|
||||
|
||||
This seems to cause problems with the SPI on the AR724x and the AR913x
|
||||
(but not the AR71xx). AR934x and subsequent chips do not look affected.
|
||||
|
||||
ToDo:
|
||||
- Analyze if this is a hardware bug or a bug in the software.
|
||||
- Send a cleaned up patch upstream.
|
||||
|
||||
Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||
|
||||
--- a/drivers/spi/spi.c
|
||||
+++ b/drivers/spi/spi.c
|
||||
@@ -791,6 +791,7 @@ static void spi_set_cs(struct spi_device
|
||||
{
|
||||
bool enable1 = enable;
|
||||
|
||||
+#if 0
|
||||
/*
|
||||
* Avoid calling into the driver (or doing delays) if the chip select
|
||||
* isn't actually changing from the last time this was called.
|
||||
@@ -801,6 +802,7 @@ static void spi_set_cs(struct spi_device
|
||||
|
||||
spi->controller->last_cs_enable = enable;
|
||||
spi->controller->last_cs_mode_high = spi->mode & SPI_CS_HIGH;
|
||||
+#endif
|
||||
|
||||
if (!spi->controller->set_cs_timing) {
|
||||
if (enable1)
|
@ -0,0 +1,89 @@
|
||||
From 4b7d7f85abac1e7ad9e8b745694e470f0729f527 Mon Sep 17 00:00:00 2001
|
||||
From: David Bauer <mail@david-bauer.net>
|
||||
Date: Wed, 3 Mar 2021 17:11:34 +0100
|
||||
Subject: [PATCH] spi: sync up initial chipselect state
|
||||
|
||||
When initially probing the SPI slave device, the call for disabling an
|
||||
SPI device without the SPI_CS_HIGH flag is not applied, as the
|
||||
condition for checking whether or not the state to be applied equals the
|
||||
one currently set evaluates to true.
|
||||
|
||||
This however might not necessarily be the case, as the chipselect might
|
||||
be active.
|
||||
|
||||
Add a force flag to spi_set_cs which allows to override this
|
||||
early access condition. Set it to false everywhere except when called
|
||||
from spi_setup to sync up the initial CS state.
|
||||
|
||||
Fixes commit d40f0b6f2e21 ("spi: Avoid setting the chip select if we don't
|
||||
need to")
|
||||
|
||||
Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||
---
|
||||
drivers/spi/spi.c | 16 ++++++++--------
|
||||
1 file changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/spi/spi.c
|
||||
+++ b/drivers/spi/spi.c
|
||||
@@ -787,7 +787,7 @@ int spi_register_board_info(struct spi_b
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
-static void spi_set_cs(struct spi_device *spi, bool enable)
|
||||
+static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
|
||||
{
|
||||
bool enable1 = enable;
|
||||
|
||||
@@ -795,7 +795,7 @@ static void spi_set_cs(struct spi_device
|
||||
* Avoid calling into the driver (or doing delays) if the chip select
|
||||
* isn't actually changing from the last time this was called.
|
||||
*/
|
||||
- if ((spi->controller->last_cs_enable == enable) &&
|
||||
+ if (!force && (spi->controller->last_cs_enable == enable) &&
|
||||
(spi->controller->last_cs_mode_high == (spi->mode & SPI_CS_HIGH)))
|
||||
return;
|
||||
|
||||
@@ -1243,7 +1243,7 @@ static int spi_transfer_one_message(stru
|
||||
struct spi_statistics *statm = &ctlr->statistics;
|
||||
struct spi_statistics *stats = &msg->spi->statistics;
|
||||
|
||||
- spi_set_cs(msg->spi, true);
|
||||
+ spi_set_cs(msg->spi, true, false);
|
||||
|
||||
SPI_STATISTICS_INCREMENT_FIELD(statm, messages);
|
||||
SPI_STATISTICS_INCREMENT_FIELD(stats, messages);
|
||||
@@ -1311,9 +1311,9 @@ fallback_pio:
|
||||
&msg->transfers)) {
|
||||
keep_cs = true;
|
||||
} else {
|
||||
- spi_set_cs(msg->spi, false);
|
||||
+ spi_set_cs(msg->spi, false, false);
|
||||
_spi_transfer_cs_change_delay(msg, xfer);
|
||||
- spi_set_cs(msg->spi, true);
|
||||
+ spi_set_cs(msg->spi, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1322,7 +1322,7 @@ fallback_pio:
|
||||
|
||||
out:
|
||||
if (ret != 0 || !keep_cs)
|
||||
- spi_set_cs(msg->spi, false);
|
||||
+ spi_set_cs(msg->spi, false, false);
|
||||
|
||||
if (msg->status == -EINPROGRESS)
|
||||
msg->status = ret;
|
||||
@@ -3400,11 +3400,11 @@ int spi_setup(struct spi_device *spi)
|
||||
*/
|
||||
status = 0;
|
||||
|
||||
- spi_set_cs(spi, false);
|
||||
+ spi_set_cs(spi, false, true);
|
||||
pm_runtime_mark_last_busy(spi->controller->dev.parent);
|
||||
pm_runtime_put_autosuspend(spi->controller->dev.parent);
|
||||
} else {
|
||||
- spi_set_cs(spi, false);
|
||||
+ spi_set_cs(spi, false, true);
|
||||
}
|
||||
|
||||
mutex_unlock(&spi->controller->io_mutex);
|
@ -17,7 +17,7 @@ Signed-off-by: Nick Hainke <vincent@systemli.org>
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -1985,7 +1985,7 @@ static int sr2_bit7_quad_enable(struct s
|
||||
@@ -1987,7 +1987,7 @@ static int sr2_bit7_quad_enable(struct s
|
||||
static int spi_nor_clear_sr_bp(struct spi_nor *nor)
|
||||
{
|
||||
int ret;
|
||||
|
@ -257,7 +257,6 @@ CONFIG_HOLES_IN_ZONE=y
|
||||
CONFIG_HOTPLUG_CPU=y
|
||||
CONFIG_HW_CONSOLE=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
CONFIG_HW_RANDOM_BCM2835=y
|
||||
CONFIG_HW_RANDOM_IPROC_RNG200=y
|
||||
CONFIG_HZ=250
|
||||
CONFIG_HZ_250=y
|
||||
|
@ -118,7 +118,7 @@ Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
|
||||
static void pxa_camera_setup_cicr(struct pxa_camera_dev *pcdev,
|
||||
unsigned long flags, __u32 pixfmt)
|
||||
{
|
||||
@@ -1598,99 +1537,78 @@ static int pxa_camera_init_videobuf2(str
|
||||
@@ -1601,99 +1540,78 @@ static int pxa_camera_init_videobuf2(str
|
||||
*/
|
||||
static int pxa_camera_set_bus_param(struct pxa_camera_dev *pcdev)
|
||||
{
|
||||
@ -271,7 +271,7 @@ Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
|
||||
}
|
||||
|
||||
static const struct pxa_mbus_pixelfmt pxa_camera_formats[] = {
|
||||
@@ -1738,11 +1656,6 @@ static int pxa_camera_get_formats(struct
|
||||
@@ -1741,11 +1659,6 @@ static int pxa_camera_get_formats(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -71,4 +71,14 @@ define Device/netgear_r8000p
|
||||
endef
|
||||
TARGET_DEVICES += netgear_r8000p
|
||||
|
||||
define Device/tplink_archer-c2300-v1
|
||||
DEVICE_VENDOR := TP-Link
|
||||
DEVICE_MODEL := Archer C2300
|
||||
DEVICE_VARIANT := v1
|
||||
DEVICE_DTS := broadcom/bcm4908/bcm4906-tplink-archer-c2300-v1
|
||||
IMAGES := bin
|
||||
IMAGE/bin := append-ubi | bcm4908img
|
||||
endef
|
||||
TARGET_DEVICES += tplink_archer-c2300-v1
|
||||
|
||||
$(eval $(call BuildImage))
|
||||
|
@ -0,0 +1 @@
|
||||
5022HNDrc7HND2221446
|
BIN
target/linux/bcm4908/image/tplink_archer-c2300-v1/nvram.nvm
Executable file
BIN
target/linux/bcm4908/image/tplink_archer-c2300-v1/nvram.nvm
Executable file
Binary file not shown.
@ -0,0 +1,21 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Fri, 5 Mar 2021 13:34:03 +0100
|
||||
Subject: [PATCH] dt-bindings: arm: bcm: document TP-Link Archer C2300 binding
|
||||
|
||||
One more BCM4906 based device.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
---
|
||||
Documentation/devicetree/bindings/arm/bcm/brcm,bcm4908.yaml | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm4908.yaml
|
||||
+++ b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm4908.yaml
|
||||
@@ -21,6 +21,7 @@ properties:
|
||||
items:
|
||||
- enum:
|
||||
- netgear,r8000p
|
||||
+ - tplink,archer-c2300-v1
|
||||
- const: brcm,bcm4906
|
||||
- const: brcm,bcm4908
|
||||
|
@ -0,0 +1,207 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Fri, 5 Mar 2021 13:36:25 +0100
|
||||
Subject: [PATCH] arm64: dts: broadcom: bcm4908: add TP-Link Archer C2300 V1
|
||||
|
||||
Archer C2300 V1 is a home router based on the BCM4906 (2 CPU cores). It
|
||||
has 512 MiB of RAM, NAND flash, USB 2.0 and USB 3.0 ports, 4 LAN ports,
|
||||
1 WAN port.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
---
|
||||
arch/arm64/boot/dts/broadcom/bcm4908/Makefile | 1 +
|
||||
.../bcm4906-tplink-archer-c2300-v1.dts | 182 ++++++++++++++++++
|
||||
2 files changed, 183 insertions(+)
|
||||
create mode 100644 arch/arm64/boot/dts/broadcom/bcm4908/bcm4906-tplink-archer-c2300-v1.dts
|
||||
|
||||
--- a/arch/arm64/boot/dts/broadcom/bcm4908/Makefile
|
||||
+++ b/arch/arm64/boot/dts/broadcom/bcm4908/Makefile
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
dtb-$(CONFIG_ARCH_BCM4908) += bcm4906-netgear-r8000p.dtb
|
||||
+dtb-$(CONFIG_ARCH_BCM4908) += bcm4906-tplink-archer-c2300-v1.dtb
|
||||
dtb-$(CONFIG_ARCH_BCM4908) += bcm4908-asus-gt-ac5300.dtb
|
||||
--- /dev/null
|
||||
+++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4906-tplink-archer-c2300-v1.dts
|
||||
@@ -0,0 +1,182 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
|
||||
+
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+#include <dt-bindings/input/input.h>
|
||||
+#include <dt-bindings/leds/common.h>
|
||||
+
|
||||
+#include "bcm4906.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ compatible = "tplink,archer-c2300-v1", "brcm,bcm4906", "brcm,bcm4908";
|
||||
+ model = "TP-Link Archer C2300 V1";
|
||||
+
|
||||
+ memory@0 {
|
||||
+ device_type = "memory";
|
||||
+ reg = <0x00 0x00 0x00 0x20000000>;
|
||||
+ };
|
||||
+
|
||||
+ leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+
|
||||
+ power-white {
|
||||
+ function = LED_FUNCTION_POWER;
|
||||
+ color = <LED_COLOR_ID_BLUE>;
|
||||
+ gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+
|
||||
+ 2ghz {
|
||||
+ function = "2ghz";
|
||||
+ color = <LED_COLOR_ID_BLUE>;
|
||||
+ gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+
|
||||
+ 5ghz {
|
||||
+ function = "5ghz";
|
||||
+ color = <LED_COLOR_ID_BLUE>;
|
||||
+ gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+
|
||||
+ wan-amber {
|
||||
+ function = LED_FUNCTION_WAN;
|
||||
+ color = <LED_COLOR_ID_AMBER>;
|
||||
+ gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>;
|
||||
+ };
|
||||
+
|
||||
+ wan-blue {
|
||||
+ function = LED_FUNCTION_WAN;
|
||||
+ color = <LED_COLOR_ID_BLUE>;
|
||||
+ gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+
|
||||
+ lan {
|
||||
+ function = LED_FUNCTION_LAN;
|
||||
+ color = <LED_COLOR_ID_BLUE>;
|
||||
+ gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+
|
||||
+ wps {
|
||||
+ function = LED_FUNCTION_WPS;
|
||||
+ color = <LED_COLOR_ID_BLUE>;
|
||||
+ gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+
|
||||
+ usb-high-white {
|
||||
+ function = "usbup";
|
||||
+ color = <LED_COLOR_ID_BLUE>;
|
||||
+ gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+
|
||||
+ usb-low-white {
|
||||
+ function = "usbdown";
|
||||
+ color = <LED_COLOR_ID_BLUE>;
|
||||
+ gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+
|
||||
+ brightness {
|
||||
+ function = LED_FUNCTION_BACKLIGHT;
|
||||
+ color = <LED_COLOR_ID_WHITE>;
|
||||
+ gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ gpio-keys-polled {
|
||||
+ compatible = "gpio-keys-polled";
|
||||
+ poll-interval = <100>;
|
||||
+
|
||||
+ brightness {
|
||||
+ label = "LEDs";
|
||||
+ linux,code = <KEY_BRIGHTNESS_ZERO>;
|
||||
+ gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+
|
||||
+ wps {
|
||||
+ label = "WPS";
|
||||
+ linux,code = <KEY_WPS_BUTTON>;
|
||||
+ gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+
|
||||
+ wifi {
|
||||
+ label = "WiFi";
|
||||
+ linux,code = <KEY_RFKILL>;
|
||||
+ gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+
|
||||
+ restart {
|
||||
+ label = "Reset";
|
||||
+ linux,code = <KEY_RESTART>;
|
||||
+ gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&usb_phy {
|
||||
+ brcm,ioc = <1>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ehci {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ohci {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&xhci {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ports {
|
||||
+ port@0 {
|
||||
+ label = "lan4";
|
||||
+ };
|
||||
+
|
||||
+ port@1 {
|
||||
+ label = "lan3";
|
||||
+ };
|
||||
+
|
||||
+ port@2 {
|
||||
+ label = "lan2";
|
||||
+ };
|
||||
+
|
||||
+ port@3 {
|
||||
+ label = "lan1";
|
||||
+ };
|
||||
+
|
||||
+ port@7 {
|
||||
+ reg = <7>;
|
||||
+ phy-mode = "internal";
|
||||
+ phy-handle = <&phy12>;
|
||||
+ label = "wan";
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&nandcs {
|
||||
+ nand-ecc-strength = <4>;
|
||||
+ nand-ecc-step-size = <512>;
|
||||
+ nand-on-flash-bbt;
|
||||
+
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ partitions {
|
||||
+ compatible = "brcm,bcm4908-partitions";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ partition@0 {
|
||||
+ label = "cferom";
|
||||
+ reg = <0x0 0x100000>;
|
||||
+ };
|
||||
+
|
||||
+ partition@100000 {
|
||||
+ compatible = "brcm,bcm4908-firmware";
|
||||
+ reg = <0x100000 0x3900000>;
|
||||
+ };
|
||||
+
|
||||
+ partition@5800000 {
|
||||
+ compatible = "brcm,bcm4908-firmware";
|
||||
+ reg = <0x3a00000 0x3900000>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
@ -1,7 +1,7 @@
|
||||
From ca6be00ca1d3a2f5b8794894e2dae175e63768f5 Mon Sep 17 00:00:00 2001
|
||||
From 90eda07518ea7e8d1b3e6445eb3633eef9f65218 Mon Sep 17 00:00:00 2001
|
||||
From: Sieng Piaw Liew <liew.s.piaw@gmail.com>
|
||||
Date: Tue, 16 Feb 2021 16:23:08 +0800
|
||||
Subject: [PATCH] bcm63xx_enet: Fix sporadic kernel panic
|
||||
Date: Mon, 22 Feb 2021 09:15:12 +0800
|
||||
Subject: [PATCH net] bcm63xx_enet: fix sporadic kernel panic
|
||||
|
||||
In ndo_stop functions, netdev_completed_queue() is called during forced
|
||||
tx reclaim, after netdev_reset_queue(). This may trigger kernel panic if
|
||||
@ -11,6 +11,9 @@ This patch moves netdev_reset_queue() to after tx reclaim, so BQL can
|
||||
complete successfully then reset.
|
||||
|
||||
Signed-off-by: Sieng Piaw Liew <liew.s.piaw@gmail.com>
|
||||
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Fixes: 4c59b0f5543d ("bcm63xx_enet: add BQL support")
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
@ -15,7 +15,7 @@
|
||||
/* 240-255: Unused at present */
|
||||
--- a/drivers/mtd/parsers/parser_imagetag.c
|
||||
+++ b/drivers/mtd/parsers/parser_imagetag.c
|
||||
@@ -132,7 +132,8 @@ static int bcm963xx_parse_imagetag_parti
|
||||
@@ -136,7 +136,8 @@ static int bcm963xx_parse_imagetag_parti
|
||||
} else {
|
||||
/* OpenWrt layout */
|
||||
rootfsaddr = kerneladdr + kernellen;
|
||||
|
@ -1,7 +1,7 @@
|
||||
From ca6be00ca1d3a2f5b8794894e2dae175e63768f5 Mon Sep 17 00:00:00 2001
|
||||
From 90eda07518ea7e8d1b3e6445eb3633eef9f65218 Mon Sep 17 00:00:00 2001
|
||||
From: Sieng Piaw Liew <liew.s.piaw@gmail.com>
|
||||
Date: Tue, 16 Feb 2021 16:23:08 +0800
|
||||
Subject: [PATCH] bcm63xx_enet: Fix sporadic kernel panic
|
||||
Date: Mon, 22 Feb 2021 09:15:12 +0800
|
||||
Subject: [PATCH net] bcm63xx_enet: fix sporadic kernel panic
|
||||
|
||||
In ndo_stop functions, netdev_completed_queue() is called during forced
|
||||
tx reclaim, after netdev_reset_queue(). This may trigger kernel panic if
|
||||
@ -11,6 +11,9 @@ This patch moves netdev_reset_queue() to after tx reclaim, so BQL can
|
||||
complete successfully then reset.
|
||||
|
||||
Signed-off-by: Sieng Piaw Liew <liew.s.piaw@gmail.com>
|
||||
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Fixes: 4c59b0f5543d ("bcm63xx_enet: add BQL support")
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
@ -15,7 +15,7 @@
|
||||
/* 240-255: Unused at present */
|
||||
--- a/drivers/mtd/parsers/parser_imagetag.c
|
||||
+++ b/drivers/mtd/parsers/parser_imagetag.c
|
||||
@@ -132,7 +132,8 @@ static int bcm963xx_parse_imagetag_parti
|
||||
@@ -136,7 +136,8 @@ static int bcm963xx_parse_imagetag_parti
|
||||
} else {
|
||||
/* OpenWrt layout */
|
||||
rootfsaddr = kerneladdr + kernellen;
|
||||
|
@ -1,337 +0,0 @@
|
||||
From 4a25324891a32d080589a6e3a4dec2be2d9e3d60 Mon Sep 17 00:00:00 2001
|
||||
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
|
||||
Date: Tue, 23 Feb 2021 14:18:58 +0100
|
||||
Subject: [PATCH] net: icmp: pass zeroed opts from icmp{,v6}_ndo_send before
|
||||
sending
|
||||
|
||||
commit ee576c47db60432c37e54b1e2b43a8ca6d3a8dca upstream.
|
||||
|
||||
The icmp{,v6}_send functions make all sorts of use of skb->cb, casting
|
||||
it with IPCB or IP6CB, assuming the skb to have come directly from the
|
||||
inet layer. But when the packet comes from the ndo layer, especially
|
||||
when forwarded, there's no telling what might be in skb->cb at that
|
||||
point. As a result, the icmp sending code risks reading bogus memory
|
||||
contents, which can result in nasty stack overflows such as this one
|
||||
reported by a user:
|
||||
|
||||
panic+0x108/0x2ea
|
||||
__stack_chk_fail+0x14/0x20
|
||||
__icmp_send+0x5bd/0x5c0
|
||||
icmp_ndo_send+0x148/0x160
|
||||
|
||||
In icmp_send, skb->cb is cast with IPCB and an ip_options struct is read
|
||||
from it. The optlen parameter there is of particular note, as it can
|
||||
induce writes beyond bounds. There are quite a few ways that can happen
|
||||
in __ip_options_echo. For example:
|
||||
|
||||
// sptr/skb are attacker-controlled skb bytes
|
||||
sptr = skb_network_header(skb);
|
||||
// dptr/dopt points to stack memory allocated by __icmp_send
|
||||
dptr = dopt->__data;
|
||||
// sopt is the corrupt skb->cb in question
|
||||
if (sopt->rr) {
|
||||
optlen = sptr[sopt->rr+1]; // corrupt skb->cb + skb->data
|
||||
soffset = sptr[sopt->rr+2]; // corrupt skb->cb + skb->data
|
||||
// this now writes potentially attacker-controlled data, over
|
||||
// flowing the stack:
|
||||
memcpy(dptr, sptr+sopt->rr, optlen);
|
||||
}
|
||||
|
||||
In the icmpv6_send case, the story is similar, but not as dire, as only
|
||||
IP6CB(skb)->iif and IP6CB(skb)->dsthao are used. The dsthao case is
|
||||
worse than the iif case, but it is passed to ipv6_find_tlv, which does
|
||||
a bit of bounds checking on the value.
|
||||
|
||||
This is easy to simulate by doing a `memset(skb->cb, 0x41,
|
||||
sizeof(skb->cb));` before calling icmp{,v6}_ndo_send, and it's only by
|
||||
good fortune and the rarity of icmp sending from that context that we've
|
||||
avoided reports like this until now. For example, in KASAN:
|
||||
|
||||
BUG: KASAN: stack-out-of-bounds in __ip_options_echo+0xa0e/0x12b0
|
||||
Write of size 38 at addr ffff888006f1f80e by task ping/89
|
||||
CPU: 2 PID: 89 Comm: ping Not tainted 5.10.0-rc7-debug+ #5
|
||||
Call Trace:
|
||||
dump_stack+0x9a/0xcc
|
||||
print_address_description.constprop.0+0x1a/0x160
|
||||
__kasan_report.cold+0x20/0x38
|
||||
kasan_report+0x32/0x40
|
||||
check_memory_region+0x145/0x1a0
|
||||
memcpy+0x39/0x60
|
||||
__ip_options_echo+0xa0e/0x12b0
|
||||
__icmp_send+0x744/0x1700
|
||||
|
||||
Actually, out of the 4 drivers that do this, only gtp zeroed the cb for
|
||||
the v4 case, while the rest did not. So this commit actually removes the
|
||||
gtp-specific zeroing, while putting the code where it belongs in the
|
||||
shared infrastructure of icmp{,v6}_ndo_send.
|
||||
|
||||
This commit fixes the issue by passing an empty IPCB or IP6CB along to
|
||||
the functions that actually do the work. For the icmp_send, this was
|
||||
already trivial, thanks to __icmp_send providing the plumbing function.
|
||||
For icmpv6_send, this required a tiny bit of refactoring to make it
|
||||
behave like the v4 case, after which it was straight forward.
|
||||
|
||||
Fixes: a2b78e9b2cac ("sunvnet: generate ICMP PTMUD messages for smaller port MTUs")
|
||||
Reported-by: SinYu <liuxyon@gmail.com>
|
||||
Reviewed-by: Willem de Bruijn <willemb@google.com>
|
||||
Link: https://lore.kernel.org/netdev/CAF=yD-LOF116aHub6RMe8vB8ZpnrrnoTdqhobEx+bvoA8AsP0w@mail.gmail.com/T/
|
||||
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
||||
Link: https://lore.kernel.org/r/20210223131858.72082-1-Jason@zx2c4.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
[Jason: backported to 5.10]
|
||||
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
||||
---
|
||||
include/linux/icmpv6.h | 17 ++++++++++++++---
|
||||
include/linux/ipv6.h | 1 -
|
||||
include/net/icmp.h | 6 +++++-
|
||||
net/ipv4/icmp.c | 5 +++--
|
||||
net/ipv6/icmp.c | 16 ++++++++--------
|
||||
net/ipv6/ip6_icmp.c | 12 +++++++-----
|
||||
6 files changed, 37 insertions(+), 20 deletions(-)
|
||||
|
||||
--- a/drivers/net/gtp.c
|
||||
+++ b/drivers/net/gtp.c
|
||||
@@ -539,7 +539,6 @@ static int gtp_build_skb_ip4(struct sk_b
|
||||
if (!skb_is_gso(skb) && (iph->frag_off & htons(IP_DF)) &&
|
||||
mtu < ntohs(iph->tot_len)) {
|
||||
netdev_dbg(dev, "packet too big, fragmentation needed\n");
|
||||
- memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
|
||||
icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
|
||||
htonl(mtu));
|
||||
goto err_rt;
|
||||
--- a/include/linux/icmpv6.h
|
||||
+++ b/include/linux/icmpv6.h
|
||||
@@ -3,6 +3,7 @@
|
||||
#define _LINUX_ICMPV6_H
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
+#include <linux/ipv6.h>
|
||||
#include <uapi/linux/icmpv6.h>
|
||||
|
||||
static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff *skb)
|
||||
@@ -15,13 +16,16 @@ static inline struct icmp6hdr *icmp6_hdr
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
|
||||
typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info,
|
||||
- const struct in6_addr *force_saddr);
|
||||
+ const struct in6_addr *force_saddr,
|
||||
+ const struct inet6_skb_parm *parm);
|
||||
#if IS_BUILTIN(CONFIG_IPV6)
|
||||
void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
|
||||
- const struct in6_addr *force_saddr);
|
||||
-static inline void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
|
||||
+ const struct in6_addr *force_saddr,
|
||||
+ const struct inet6_skb_parm *parm);
|
||||
+static inline void __icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
|
||||
+ const struct inet6_skb_parm *parm)
|
||||
{
|
||||
- icmp6_send(skb, type, code, info, NULL);
|
||||
+ icmp6_send(skb, type, code, info, NULL, parm);
|
||||
}
|
||||
static inline int inet6_register_icmp_sender(ip6_icmp_send_t *fn)
|
||||
{
|
||||
@@ -34,18 +38,28 @@ static inline int inet6_unregister_icmp_
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
-extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info);
|
||||
+extern void __icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
|
||||
+ const struct inet6_skb_parm *parm);
|
||||
extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
|
||||
extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
|
||||
#endif
|
||||
|
||||
+static inline void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
|
||||
+{
|
||||
+ __icmpv6_send(skb, type, code, info, IP6CB(skb));
|
||||
+}
|
||||
+
|
||||
int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
|
||||
unsigned int data_len);
|
||||
|
||||
#if IS_ENABLED(CONFIG_NF_NAT)
|
||||
void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info);
|
||||
#else
|
||||
-#define icmpv6_ndo_send icmpv6_send
|
||||
+static inline void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info)
|
||||
+{
|
||||
+ struct inet6_skb_parm parm = { 0 };
|
||||
+ __icmpv6_send(skb_in, type, code, info, &parm);
|
||||
+}
|
||||
#endif
|
||||
|
||||
#else
|
||||
--- a/include/linux/ipv6.h
|
||||
+++ b/include/linux/ipv6.h
|
||||
@@ -84,7 +84,6 @@ struct ipv6_params {
|
||||
__s32 autoconf;
|
||||
};
|
||||
extern struct ipv6_params ipv6_defaults;
|
||||
-#include <linux/icmpv6.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/udp.h>
|
||||
|
||||
--- a/include/net/icmp.h
|
||||
+++ b/include/net/icmp.h
|
||||
@@ -46,7 +46,11 @@ static inline void icmp_send(struct sk_b
|
||||
#if IS_ENABLED(CONFIG_NF_NAT)
|
||||
void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info);
|
||||
#else
|
||||
-#define icmp_ndo_send icmp_send
|
||||
+static inline void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info)
|
||||
+{
|
||||
+ struct ip_options opts = { 0 };
|
||||
+ __icmp_send(skb_in, type, code, info, &opts);
|
||||
+}
|
||||
#endif
|
||||
|
||||
int icmp_rcv(struct sk_buff *skb);
|
||||
--- a/net/ipv4/icmp.c
|
||||
+++ b/net/ipv4/icmp.c
|
||||
@@ -775,13 +775,14 @@ EXPORT_SYMBOL(__icmp_send);
|
||||
void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info)
|
||||
{
|
||||
struct sk_buff *cloned_skb = NULL;
|
||||
+ struct ip_options opts = { 0 };
|
||||
enum ip_conntrack_info ctinfo;
|
||||
struct nf_conn *ct;
|
||||
__be32 orig_ip;
|
||||
|
||||
ct = nf_ct_get(skb_in, &ctinfo);
|
||||
if (!ct || !(ct->status & IPS_SRC_NAT)) {
|
||||
- icmp_send(skb_in, type, code, info);
|
||||
+ __icmp_send(skb_in, type, code, info, &opts);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -796,7 +797,7 @@ void icmp_ndo_send(struct sk_buff *skb_i
|
||||
|
||||
orig_ip = ip_hdr(skb_in)->saddr;
|
||||
ip_hdr(skb_in)->saddr = ct->tuplehash[0].tuple.src.u3.ip;
|
||||
- icmp_send(skb_in, type, code, info);
|
||||
+ __icmp_send(skb_in, type, code, info, &opts);
|
||||
ip_hdr(skb_in)->saddr = orig_ip;
|
||||
out:
|
||||
consume_skb(cloned_skb);
|
||||
--- a/net/ipv6/icmp.c
|
||||
+++ b/net/ipv6/icmp.c
|
||||
@@ -331,10 +331,9 @@ static int icmpv6_getfrag(void *from, ch
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6_MIP6)
|
||||
-static void mip6_addr_swap(struct sk_buff *skb)
|
||||
+static void mip6_addr_swap(struct sk_buff *skb, const struct inet6_skb_parm *opt)
|
||||
{
|
||||
struct ipv6hdr *iph = ipv6_hdr(skb);
|
||||
- struct inet6_skb_parm *opt = IP6CB(skb);
|
||||
struct ipv6_destopt_hao *hao;
|
||||
struct in6_addr tmp;
|
||||
int off;
|
||||
@@ -351,7 +350,7 @@ static void mip6_addr_swap(struct sk_buf
|
||||
}
|
||||
}
|
||||
#else
|
||||
-static inline void mip6_addr_swap(struct sk_buff *skb) {}
|
||||
+static inline void mip6_addr_swap(struct sk_buff *skb, const struct inet6_skb_parm *opt) {}
|
||||
#endif
|
||||
|
||||
static struct dst_entry *icmpv6_route_lookup(struct net *net,
|
||||
@@ -446,7 +445,8 @@ static int icmp6_iif(const struct sk_buf
|
||||
* Send an ICMP message in response to a packet in error
|
||||
*/
|
||||
void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
|
||||
- const struct in6_addr *force_saddr)
|
||||
+ const struct in6_addr *force_saddr,
|
||||
+ const struct inet6_skb_parm *parm)
|
||||
{
|
||||
struct inet6_dev *idev = NULL;
|
||||
struct ipv6hdr *hdr = ipv6_hdr(skb);
|
||||
@@ -542,7 +542,7 @@ void icmp6_send(struct sk_buff *skb, u8
|
||||
if (!(skb->dev->flags & IFF_LOOPBACK) && !icmpv6_global_allow(net, type))
|
||||
goto out_bh_enable;
|
||||
|
||||
- mip6_addr_swap(skb);
|
||||
+ mip6_addr_swap(skb, parm);
|
||||
|
||||
sk = icmpv6_xmit_lock(net);
|
||||
if (!sk)
|
||||
@@ -559,7 +559,7 @@ void icmp6_send(struct sk_buff *skb, u8
|
||||
/* select a more meaningful saddr from input if */
|
||||
struct net_device *in_netdev;
|
||||
|
||||
- in_netdev = dev_get_by_index(net, IP6CB(skb)->iif);
|
||||
+ in_netdev = dev_get_by_index(net, parm->iif);
|
||||
if (in_netdev) {
|
||||
ipv6_dev_get_saddr(net, in_netdev, &fl6.daddr,
|
||||
inet6_sk(sk)->srcprefs,
|
||||
@@ -640,7 +640,7 @@ EXPORT_SYMBOL(icmp6_send);
|
||||
*/
|
||||
void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
|
||||
{
|
||||
- icmp6_send(skb, ICMPV6_PARAMPROB, code, pos, NULL);
|
||||
+ icmp6_send(skb, ICMPV6_PARAMPROB, code, pos, NULL, IP6CB(skb));
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
@@ -697,10 +697,10 @@ int ip6_err_gen_icmpv6_unreach(struct sk
|
||||
}
|
||||
if (type == ICMP_TIME_EXCEEDED)
|
||||
icmp6_send(skb2, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
|
||||
- info, &temp_saddr);
|
||||
+ info, &temp_saddr, IP6CB(skb2));
|
||||
else
|
||||
icmp6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH,
|
||||
- info, &temp_saddr);
|
||||
+ info, &temp_saddr, IP6CB(skb2));
|
||||
if (rt)
|
||||
ip6_rt_put(rt);
|
||||
|
||||
--- a/net/ipv6/ip6_icmp.c
|
||||
+++ b/net/ipv6/ip6_icmp.c
|
||||
@@ -33,23 +33,25 @@ int inet6_unregister_icmp_sender(ip6_icm
|
||||
}
|
||||
EXPORT_SYMBOL(inet6_unregister_icmp_sender);
|
||||
|
||||
-void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
|
||||
+void __icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
|
||||
+ const struct inet6_skb_parm *parm)
|
||||
{
|
||||
ip6_icmp_send_t *send;
|
||||
|
||||
rcu_read_lock();
|
||||
send = rcu_dereference(ip6_icmp_send);
|
||||
if (send)
|
||||
- send(skb, type, code, info, NULL);
|
||||
+ send(skb, type, code, info, NULL, parm);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
-EXPORT_SYMBOL(icmpv6_send);
|
||||
+EXPORT_SYMBOL(__icmpv6_send);
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_NF_NAT)
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info)
|
||||
{
|
||||
+ struct inet6_skb_parm parm = { 0 };
|
||||
struct sk_buff *cloned_skb = NULL;
|
||||
enum ip_conntrack_info ctinfo;
|
||||
struct in6_addr orig_ip;
|
||||
@@ -57,7 +59,7 @@ void icmpv6_ndo_send(struct sk_buff *skb
|
||||
|
||||
ct = nf_ct_get(skb_in, &ctinfo);
|
||||
if (!ct || !(ct->status & IPS_SRC_NAT)) {
|
||||
- icmpv6_send(skb_in, type, code, info);
|
||||
+ __icmpv6_send(skb_in, type, code, info, &parm);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -72,7 +74,7 @@ void icmpv6_ndo_send(struct sk_buff *skb
|
||||
|
||||
orig_ip = ipv6_hdr(skb_in)->saddr;
|
||||
ipv6_hdr(skb_in)->saddr = ct->tuplehash[0].tuple.src.u3.in6;
|
||||
- icmpv6_send(skb_in, type, code, info);
|
||||
+ __icmpv6_send(skb_in, type, code, info, &parm);
|
||||
ipv6_hdr(skb_in)->saddr = orig_ip;
|
||||
out:
|
||||
consume_skb(cloned_skb);
|
@ -22,7 +22,7 @@ Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
||||
--- a/drivers/net/wireguard/peer.h
|
||||
+++ b/drivers/net/wireguard/peer.h
|
||||
@@ -39,6 +39,7 @@ struct wg_peer {
|
||||
struct crypt_queue tx_queue, rx_queue;
|
||||
struct prev_queue tx_queue, rx_queue;
|
||||
struct sk_buff_head staged_packet_queue;
|
||||
int serial_work_cpu;
|
||||
+ bool is_dead;
|
||||
|
@ -1,47 +0,0 @@
|
||||
From 49da2a610d63cef849f0095e601821ad6edfbef7 Mon Sep 17 00:00:00 2001
|
||||
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
|
||||
Date: Mon, 22 Feb 2021 17:25:47 +0100
|
||||
Subject: [PATCH] wireguard: device: do not generate ICMP for non-IP packets
|
||||
|
||||
commit 99fff5264e7ab06f45b0ad60243475be0a8d0559 upstream.
|
||||
|
||||
If skb->protocol doesn't match the actual skb->data header, it's
|
||||
probably not a good idea to pass it off to icmp{,v6}_ndo_send, which is
|
||||
expecting to reply to a valid IP packet. So this commit has that early
|
||||
mismatch case jump to a later error label.
|
||||
|
||||
Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
|
||||
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
||||
---
|
||||
drivers/net/wireguard/device.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireguard/device.c
|
||||
+++ b/drivers/net/wireguard/device.c
|
||||
@@ -138,7 +138,7 @@ static netdev_tx_t wg_xmit(struct sk_buf
|
||||
else if (skb->protocol == htons(ETH_P_IPV6))
|
||||
net_dbg_ratelimited("%s: No peer has allowed IPs matching %pI6\n",
|
||||
dev->name, &ipv6_hdr(skb)->daddr);
|
||||
- goto err;
|
||||
+ goto err_icmp;
|
||||
}
|
||||
|
||||
family = READ_ONCE(peer->endpoint.addr.sa_family);
|
||||
@@ -201,12 +201,13 @@ static netdev_tx_t wg_xmit(struct sk_buf
|
||||
|
||||
err_peer:
|
||||
wg_peer_put(peer);
|
||||
-err:
|
||||
- ++dev->stats.tx_errors;
|
||||
+err_icmp:
|
||||
if (skb->protocol == htons(ETH_P_IP))
|
||||
icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
|
||||
else if (skb->protocol == htons(ETH_P_IPV6))
|
||||
icmpv6_ndo_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0);
|
||||
+err:
|
||||
+ ++dev->stats.tx_errors;
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
@ -1,560 +0,0 @@
|
||||
From 1771bbcc5bc99f569dd82ec9e1b7c397a2fb50ac Mon Sep 17 00:00:00 2001
|
||||
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
|
||||
Date: Mon, 22 Feb 2021 17:25:48 +0100
|
||||
Subject: [PATCH] wireguard: queueing: get rid of per-peer ring buffers
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
commit 8b5553ace83cced775eefd0f3f18b5c6214ccf7a upstream.
|
||||
|
||||
Having two ring buffers per-peer means that every peer results in two
|
||||
massive ring allocations. On an 8-core x86_64 machine, this commit
|
||||
reduces the per-peer allocation from 18,688 bytes to 1,856 bytes, which
|
||||
is an 90% reduction. Ninety percent! With some single-machine
|
||||
deployments approaching 500,000 peers, we're talking about a reduction
|
||||
from 7 gigs of memory down to 700 megs of memory.
|
||||
|
||||
In order to get rid of these per-peer allocations, this commit switches
|
||||
to using a list-based queueing approach. Currently GSO fragments are
|
||||
chained together using the skb->next pointer (the skb_list_* singly
|
||||
linked list approach), so we form the per-peer queue around the unused
|
||||
skb->prev pointer (which sort of makes sense because the links are
|
||||
pointing backwards). Use of skb_queue_* is not possible here, because
|
||||
that is based on doubly linked lists and spinlocks. Multiple cores can
|
||||
write into the queue at any given time, because its writes occur in the
|
||||
start_xmit path or in the udp_recv path. But reads happen in a single
|
||||
workqueue item per-peer, amounting to a multi-producer, single-consumer
|
||||
paradigm.
|
||||
|
||||
The MPSC queue is implemented locklessly and never blocks. However, it
|
||||
is not linearizable (though it is serializable), with a very tight and
|
||||
unlikely race on writes, which, when hit (some tiny fraction of the
|
||||
0.15% of partial adds on a fully loaded 16-core x86_64 system), causes
|
||||
the queue reader to terminate early. However, because every packet sent
|
||||
queues up the same workqueue item after it is fully added, the worker
|
||||
resumes again, and stopping early isn't actually a problem, since at
|
||||
that point the packet wouldn't have yet been added to the encryption
|
||||
queue. These properties allow us to avoid disabling interrupts or
|
||||
spinning. The design is based on Dmitry Vyukov's algorithm [1].
|
||||
|
||||
Performance-wise, ordinarily list-based queues aren't preferable to
|
||||
ringbuffers, because of cache misses when following pointers around.
|
||||
However, we *already* have to follow the adjacent pointers when working
|
||||
through fragments, so there shouldn't actually be any change there. A
|
||||
potential downside is that dequeueing is a bit more complicated, but the
|
||||
ptr_ring structure used prior had a spinlock when dequeueing, so all and
|
||||
all the difference appears to be a wash.
|
||||
|
||||
Actually, from profiling, the biggest performance hit, by far, of this
|
||||
commit winds up being atomic_add_unless(count, 1, max) and atomic_
|
||||
dec(count), which account for the majority of CPU time, according to
|
||||
perf. In that sense, the previous ring buffer was superior in that it
|
||||
could check if it was full by head==tail, which the list-based approach
|
||||
cannot do.
|
||||
|
||||
But all and all, this enables us to get massive memory savings, allowing
|
||||
WireGuard to scale for real world deployments, without taking much of a
|
||||
performance hit.
|
||||
|
||||
[1] http://www.1024cores.net/home/lock-free-algorithms/queues/intrusive-mpsc-node-based-queue
|
||||
|
||||
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
|
||||
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
|
||||
Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
|
||||
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
||||
---
|
||||
drivers/net/wireguard/device.c | 12 ++---
|
||||
drivers/net/wireguard/device.h | 15 +++---
|
||||
drivers/net/wireguard/peer.c | 28 ++++-------
|
||||
drivers/net/wireguard/peer.h | 4 +-
|
||||
drivers/net/wireguard/queueing.c | 86 +++++++++++++++++++++++++-------
|
||||
drivers/net/wireguard/queueing.h | 45 ++++++++++++-----
|
||||
drivers/net/wireguard/receive.c | 16 +++---
|
||||
drivers/net/wireguard/send.c | 31 ++++--------
|
||||
8 files changed, 144 insertions(+), 93 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireguard/device.c
|
||||
+++ b/drivers/net/wireguard/device.c
|
||||
@@ -235,8 +235,8 @@ static void wg_destruct(struct net_devic
|
||||
destroy_workqueue(wg->handshake_receive_wq);
|
||||
destroy_workqueue(wg->handshake_send_wq);
|
||||
destroy_workqueue(wg->packet_crypt_wq);
|
||||
- wg_packet_queue_free(&wg->decrypt_queue, true);
|
||||
- wg_packet_queue_free(&wg->encrypt_queue, true);
|
||||
+ wg_packet_queue_free(&wg->decrypt_queue);
|
||||
+ wg_packet_queue_free(&wg->encrypt_queue);
|
||||
rcu_barrier(); /* Wait for all the peers to be actually freed. */
|
||||
wg_ratelimiter_uninit();
|
||||
memzero_explicit(&wg->static_identity, sizeof(wg->static_identity));
|
||||
@@ -338,12 +338,12 @@ static int wg_newlink(struct net *src_ne
|
||||
goto err_destroy_handshake_send;
|
||||
|
||||
ret = wg_packet_queue_init(&wg->encrypt_queue, wg_packet_encrypt_worker,
|
||||
- true, MAX_QUEUED_PACKETS);
|
||||
+ MAX_QUEUED_PACKETS);
|
||||
if (ret < 0)
|
||||
goto err_destroy_packet_crypt;
|
||||
|
||||
ret = wg_packet_queue_init(&wg->decrypt_queue, wg_packet_decrypt_worker,
|
||||
- true, MAX_QUEUED_PACKETS);
|
||||
+ MAX_QUEUED_PACKETS);
|
||||
if (ret < 0)
|
||||
goto err_free_encrypt_queue;
|
||||
|
||||
@@ -368,9 +368,9 @@ static int wg_newlink(struct net *src_ne
|
||||
err_uninit_ratelimiter:
|
||||
wg_ratelimiter_uninit();
|
||||
err_free_decrypt_queue:
|
||||
- wg_packet_queue_free(&wg->decrypt_queue, true);
|
||||
+ wg_packet_queue_free(&wg->decrypt_queue);
|
||||
err_free_encrypt_queue:
|
||||
- wg_packet_queue_free(&wg->encrypt_queue, true);
|
||||
+ wg_packet_queue_free(&wg->encrypt_queue);
|
||||
err_destroy_packet_crypt:
|
||||
destroy_workqueue(wg->packet_crypt_wq);
|
||||
err_destroy_handshake_send:
|
||||
--- a/drivers/net/wireguard/device.h
|
||||
+++ b/drivers/net/wireguard/device.h
|
||||
@@ -27,13 +27,14 @@ struct multicore_worker {
|
||||
|
||||
struct crypt_queue {
|
||||
struct ptr_ring ring;
|
||||
- union {
|
||||
- struct {
|
||||
- struct multicore_worker __percpu *worker;
|
||||
- int last_cpu;
|
||||
- };
|
||||
- struct work_struct work;
|
||||
- };
|
||||
+ struct multicore_worker __percpu *worker;
|
||||
+ int last_cpu;
|
||||
+};
|
||||
+
|
||||
+struct prev_queue {
|
||||
+ struct sk_buff *head, *tail, *peeked;
|
||||
+ struct { struct sk_buff *next, *prev; } empty; // Match first 2 members of struct sk_buff.
|
||||
+ atomic_t count;
|
||||
};
|
||||
|
||||
struct wg_device {
|
||||
--- a/drivers/net/wireguard/peer.c
|
||||
+++ b/drivers/net/wireguard/peer.c
|
||||
@@ -32,27 +32,22 @@ struct wg_peer *wg_peer_create(struct wg
|
||||
peer = kzalloc(sizeof(*peer), GFP_KERNEL);
|
||||
if (unlikely(!peer))
|
||||
return ERR_PTR(ret);
|
||||
- peer->device = wg;
|
||||
+ if (dst_cache_init(&peer->endpoint_cache, GFP_KERNEL))
|
||||
+ goto err;
|
||||
|
||||
+ peer->device = wg;
|
||||
wg_noise_handshake_init(&peer->handshake, &wg->static_identity,
|
||||
public_key, preshared_key, peer);
|
||||
- if (dst_cache_init(&peer->endpoint_cache, GFP_KERNEL))
|
||||
- goto err_1;
|
||||
- if (wg_packet_queue_init(&peer->tx_queue, wg_packet_tx_worker, false,
|
||||
- MAX_QUEUED_PACKETS))
|
||||
- goto err_2;
|
||||
- if (wg_packet_queue_init(&peer->rx_queue, NULL, false,
|
||||
- MAX_QUEUED_PACKETS))
|
||||
- goto err_3;
|
||||
-
|
||||
peer->internal_id = atomic64_inc_return(&peer_counter);
|
||||
peer->serial_work_cpu = nr_cpumask_bits;
|
||||
wg_cookie_init(&peer->latest_cookie);
|
||||
wg_timers_init(peer);
|
||||
wg_cookie_checker_precompute_peer_keys(peer);
|
||||
spin_lock_init(&peer->keypairs.keypair_update_lock);
|
||||
- INIT_WORK(&peer->transmit_handshake_work,
|
||||
- wg_packet_handshake_send_worker);
|
||||
+ INIT_WORK(&peer->transmit_handshake_work, wg_packet_handshake_send_worker);
|
||||
+ INIT_WORK(&peer->transmit_packet_work, wg_packet_tx_worker);
|
||||
+ wg_prev_queue_init(&peer->tx_queue);
|
||||
+ wg_prev_queue_init(&peer->rx_queue);
|
||||
rwlock_init(&peer->endpoint_lock);
|
||||
kref_init(&peer->refcount);
|
||||
skb_queue_head_init(&peer->staged_packet_queue);
|
||||
@@ -68,11 +63,7 @@ struct wg_peer *wg_peer_create(struct wg
|
||||
pr_debug("%s: Peer %llu created\n", wg->dev->name, peer->internal_id);
|
||||
return peer;
|
||||
|
||||
-err_3:
|
||||
- wg_packet_queue_free(&peer->tx_queue, false);
|
||||
-err_2:
|
||||
- dst_cache_destroy(&peer->endpoint_cache);
|
||||
-err_1:
|
||||
+err:
|
||||
kfree(peer);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
@@ -197,8 +188,7 @@ static void rcu_release(struct rcu_head
|
||||
struct wg_peer *peer = container_of(rcu, struct wg_peer, rcu);
|
||||
|
||||
dst_cache_destroy(&peer->endpoint_cache);
|
||||
- wg_packet_queue_free(&peer->rx_queue, false);
|
||||
- wg_packet_queue_free(&peer->tx_queue, false);
|
||||
+ WARN_ON(wg_prev_queue_peek(&peer->tx_queue) || wg_prev_queue_peek(&peer->rx_queue));
|
||||
|
||||
/* The final zeroing takes care of clearing any remaining handshake key
|
||||
* material and other potentially sensitive information.
|
||||
--- a/drivers/net/wireguard/peer.h
|
||||
+++ b/drivers/net/wireguard/peer.h
|
||||
@@ -36,7 +36,7 @@ struct endpoint {
|
||||
|
||||
struct wg_peer {
|
||||
struct wg_device *device;
|
||||
- struct crypt_queue tx_queue, rx_queue;
|
||||
+ struct prev_queue tx_queue, rx_queue;
|
||||
struct sk_buff_head staged_packet_queue;
|
||||
int serial_work_cpu;
|
||||
bool is_dead;
|
||||
@@ -46,7 +46,7 @@ struct wg_peer {
|
||||
rwlock_t endpoint_lock;
|
||||
struct noise_handshake handshake;
|
||||
atomic64_t last_sent_handshake;
|
||||
- struct work_struct transmit_handshake_work, clear_peer_work;
|
||||
+ struct work_struct transmit_handshake_work, clear_peer_work, transmit_packet_work;
|
||||
struct cookie latest_cookie;
|
||||
struct hlist_node pubkey_hash;
|
||||
u64 rx_bytes, tx_bytes;
|
||||
--- a/drivers/net/wireguard/queueing.c
|
||||
+++ b/drivers/net/wireguard/queueing.c
|
||||
@@ -9,8 +9,7 @@ struct multicore_worker __percpu *
|
||||
wg_packet_percpu_multicore_worker_alloc(work_func_t function, void *ptr)
|
||||
{
|
||||
int cpu;
|
||||
- struct multicore_worker __percpu *worker =
|
||||
- alloc_percpu(struct multicore_worker);
|
||||
+ struct multicore_worker __percpu *worker = alloc_percpu(struct multicore_worker);
|
||||
|
||||
if (!worker)
|
||||
return NULL;
|
||||
@@ -23,7 +22,7 @@ wg_packet_percpu_multicore_worker_alloc(
|
||||
}
|
||||
|
||||
int wg_packet_queue_init(struct crypt_queue *queue, work_func_t function,
|
||||
- bool multicore, unsigned int len)
|
||||
+ unsigned int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -31,25 +30,78 @@ int wg_packet_queue_init(struct crypt_qu
|
||||
ret = ptr_ring_init(&queue->ring, len, GFP_KERNEL);
|
||||
if (ret)
|
||||
return ret;
|
||||
- if (function) {
|
||||
- if (multicore) {
|
||||
- queue->worker = wg_packet_percpu_multicore_worker_alloc(
|
||||
- function, queue);
|
||||
- if (!queue->worker) {
|
||||
- ptr_ring_cleanup(&queue->ring, NULL);
|
||||
- return -ENOMEM;
|
||||
- }
|
||||
- } else {
|
||||
- INIT_WORK(&queue->work, function);
|
||||
- }
|
||||
+ queue->worker = wg_packet_percpu_multicore_worker_alloc(function, queue);
|
||||
+ if (!queue->worker) {
|
||||
+ ptr_ring_cleanup(&queue->ring, NULL);
|
||||
+ return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
-void wg_packet_queue_free(struct crypt_queue *queue, bool multicore)
|
||||
+void wg_packet_queue_free(struct crypt_queue *queue)
|
||||
{
|
||||
- if (multicore)
|
||||
- free_percpu(queue->worker);
|
||||
+ free_percpu(queue->worker);
|
||||
WARN_ON(!__ptr_ring_empty(&queue->ring));
|
||||
ptr_ring_cleanup(&queue->ring, NULL);
|
||||
}
|
||||
+
|
||||
+#define NEXT(skb) ((skb)->prev)
|
||||
+#define STUB(queue) ((struct sk_buff *)&queue->empty)
|
||||
+
|
||||
+void wg_prev_queue_init(struct prev_queue *queue)
|
||||
+{
|
||||
+ NEXT(STUB(queue)) = NULL;
|
||||
+ queue->head = queue->tail = STUB(queue);
|
||||
+ queue->peeked = NULL;
|
||||
+ atomic_set(&queue->count, 0);
|
||||
+ BUILD_BUG_ON(
|
||||
+ offsetof(struct sk_buff, next) != offsetof(struct prev_queue, empty.next) -
|
||||
+ offsetof(struct prev_queue, empty) ||
|
||||
+ offsetof(struct sk_buff, prev) != offsetof(struct prev_queue, empty.prev) -
|
||||
+ offsetof(struct prev_queue, empty));
|
||||
+}
|
||||
+
|
||||
+static void __wg_prev_queue_enqueue(struct prev_queue *queue, struct sk_buff *skb)
|
||||
+{
|
||||
+ WRITE_ONCE(NEXT(skb), NULL);
|
||||
+ WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
|
||||
+}
|
||||
+
|
||||
+bool wg_prev_queue_enqueue(struct prev_queue *queue, struct sk_buff *skb)
|
||||
+{
|
||||
+ if (!atomic_add_unless(&queue->count, 1, MAX_QUEUED_PACKETS))
|
||||
+ return false;
|
||||
+ __wg_prev_queue_enqueue(queue, skb);
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+struct sk_buff *wg_prev_queue_dequeue(struct prev_queue *queue)
|
||||
+{
|
||||
+ struct sk_buff *tail = queue->tail, *next = smp_load_acquire(&NEXT(tail));
|
||||
+
|
||||
+ if (tail == STUB(queue)) {
|
||||
+ if (!next)
|
||||
+ return NULL;
|
||||
+ queue->tail = next;
|
||||
+ tail = next;
|
||||
+ next = smp_load_acquire(&NEXT(next));
|
||||
+ }
|
||||
+ if (next) {
|
||||
+ queue->tail = next;
|
||||
+ atomic_dec(&queue->count);
|
||||
+ return tail;
|
||||
+ }
|
||||
+ if (tail != READ_ONCE(queue->head))
|
||||
+ return NULL;
|
||||
+ __wg_prev_queue_enqueue(queue, STUB(queue));
|
||||
+ next = smp_load_acquire(&NEXT(tail));
|
||||
+ if (next) {
|
||||
+ queue->tail = next;
|
||||
+ atomic_dec(&queue->count);
|
||||
+ return tail;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+#undef NEXT
|
||||
+#undef STUB
|
||||
--- a/drivers/net/wireguard/queueing.h
|
||||
+++ b/drivers/net/wireguard/queueing.h
|
||||
@@ -17,12 +17,13 @@ struct wg_device;
|
||||
struct wg_peer;
|
||||
struct multicore_worker;
|
||||
struct crypt_queue;
|
||||
+struct prev_queue;
|
||||
struct sk_buff;
|
||||
|
||||
/* queueing.c APIs: */
|
||||
int wg_packet_queue_init(struct crypt_queue *queue, work_func_t function,
|
||||
- bool multicore, unsigned int len);
|
||||
-void wg_packet_queue_free(struct crypt_queue *queue, bool multicore);
|
||||
+ unsigned int len);
|
||||
+void wg_packet_queue_free(struct crypt_queue *queue);
|
||||
struct multicore_worker __percpu *
|
||||
wg_packet_percpu_multicore_worker_alloc(work_func_t function, void *ptr);
|
||||
|
||||
@@ -135,8 +136,31 @@ static inline int wg_cpumask_next_online
|
||||
return cpu;
|
||||
}
|
||||
|
||||
+void wg_prev_queue_init(struct prev_queue *queue);
|
||||
+
|
||||
+/* Multi producer */
|
||||
+bool wg_prev_queue_enqueue(struct prev_queue *queue, struct sk_buff *skb);
|
||||
+
|
||||
+/* Single consumer */
|
||||
+struct sk_buff *wg_prev_queue_dequeue(struct prev_queue *queue);
|
||||
+
|
||||
+/* Single consumer */
|
||||
+static inline struct sk_buff *wg_prev_queue_peek(struct prev_queue *queue)
|
||||
+{
|
||||
+ if (queue->peeked)
|
||||
+ return queue->peeked;
|
||||
+ queue->peeked = wg_prev_queue_dequeue(queue);
|
||||
+ return queue->peeked;
|
||||
+}
|
||||
+
|
||||
+/* Single consumer */
|
||||
+static inline void wg_prev_queue_drop_peeked(struct prev_queue *queue)
|
||||
+{
|
||||
+ queue->peeked = NULL;
|
||||
+}
|
||||
+
|
||||
static inline int wg_queue_enqueue_per_device_and_peer(
|
||||
- struct crypt_queue *device_queue, struct crypt_queue *peer_queue,
|
||||
+ struct crypt_queue *device_queue, struct prev_queue *peer_queue,
|
||||
struct sk_buff *skb, struct workqueue_struct *wq, int *next_cpu)
|
||||
{
|
||||
int cpu;
|
||||
@@ -145,8 +169,9 @@ static inline int wg_queue_enqueue_per_d
|
||||
/* We first queue this up for the peer ingestion, but the consumer
|
||||
* will wait for the state to change to CRYPTED or DEAD before.
|
||||
*/
|
||||
- if (unlikely(ptr_ring_produce_bh(&peer_queue->ring, skb)))
|
||||
+ if (unlikely(!wg_prev_queue_enqueue(peer_queue, skb)))
|
||||
return -ENOSPC;
|
||||
+
|
||||
/* Then we queue it up in the device queue, which consumes the
|
||||
* packet as soon as it can.
|
||||
*/
|
||||
@@ -157,9 +182,7 @@ static inline int wg_queue_enqueue_per_d
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static inline void wg_queue_enqueue_per_peer(struct crypt_queue *queue,
|
||||
- struct sk_buff *skb,
|
||||
- enum packet_state state)
|
||||
+static inline void wg_queue_enqueue_per_peer_tx(struct sk_buff *skb, enum packet_state state)
|
||||
{
|
||||
/* We take a reference, because as soon as we call atomic_set, the
|
||||
* peer can be freed from below us.
|
||||
@@ -167,14 +190,12 @@ static inline void wg_queue_enqueue_per_
|
||||
struct wg_peer *peer = wg_peer_get(PACKET_PEER(skb));
|
||||
|
||||
atomic_set_release(&PACKET_CB(skb)->state, state);
|
||||
- queue_work_on(wg_cpumask_choose_online(&peer->serial_work_cpu,
|
||||
- peer->internal_id),
|
||||
- peer->device->packet_crypt_wq, &queue->work);
|
||||
+ queue_work_on(wg_cpumask_choose_online(&peer->serial_work_cpu, peer->internal_id),
|
||||
+ peer->device->packet_crypt_wq, &peer->transmit_packet_work);
|
||||
wg_peer_put(peer);
|
||||
}
|
||||
|
||||
-static inline void wg_queue_enqueue_per_peer_napi(struct sk_buff *skb,
|
||||
- enum packet_state state)
|
||||
+static inline void wg_queue_enqueue_per_peer_rx(struct sk_buff *skb, enum packet_state state)
|
||||
{
|
||||
/* We take a reference, because as soon as we call atomic_set, the
|
||||
* peer can be freed from below us.
|
||||
--- a/drivers/net/wireguard/receive.c
|
||||
+++ b/drivers/net/wireguard/receive.c
|
||||
@@ -444,7 +444,6 @@ packet_processed:
|
||||
int wg_packet_rx_poll(struct napi_struct *napi, int budget)
|
||||
{
|
||||
struct wg_peer *peer = container_of(napi, struct wg_peer, napi);
|
||||
- struct crypt_queue *queue = &peer->rx_queue;
|
||||
struct noise_keypair *keypair;
|
||||
struct endpoint endpoint;
|
||||
enum packet_state state;
|
||||
@@ -455,11 +454,10 @@ int wg_packet_rx_poll(struct napi_struct
|
||||
if (unlikely(budget <= 0))
|
||||
return 0;
|
||||
|
||||
- while ((skb = __ptr_ring_peek(&queue->ring)) != NULL &&
|
||||
+ while ((skb = wg_prev_queue_peek(&peer->rx_queue)) != NULL &&
|
||||
(state = atomic_read_acquire(&PACKET_CB(skb)->state)) !=
|
||||
PACKET_STATE_UNCRYPTED) {
|
||||
- __ptr_ring_discard_one(&queue->ring);
|
||||
- peer = PACKET_PEER(skb);
|
||||
+ wg_prev_queue_drop_peeked(&peer->rx_queue);
|
||||
keypair = PACKET_CB(skb)->keypair;
|
||||
free = true;
|
||||
|
||||
@@ -508,7 +506,7 @@ void wg_packet_decrypt_worker(struct wor
|
||||
enum packet_state state =
|
||||
likely(decrypt_packet(skb, PACKET_CB(skb)->keypair)) ?
|
||||
PACKET_STATE_CRYPTED : PACKET_STATE_DEAD;
|
||||
- wg_queue_enqueue_per_peer_napi(skb, state);
|
||||
+ wg_queue_enqueue_per_peer_rx(skb, state);
|
||||
if (need_resched())
|
||||
cond_resched();
|
||||
}
|
||||
@@ -531,12 +529,10 @@ static void wg_packet_consume_data(struc
|
||||
if (unlikely(READ_ONCE(peer->is_dead)))
|
||||
goto err;
|
||||
|
||||
- ret = wg_queue_enqueue_per_device_and_peer(&wg->decrypt_queue,
|
||||
- &peer->rx_queue, skb,
|
||||
- wg->packet_crypt_wq,
|
||||
- &wg->decrypt_queue.last_cpu);
|
||||
+ ret = wg_queue_enqueue_per_device_and_peer(&wg->decrypt_queue, &peer->rx_queue, skb,
|
||||
+ wg->packet_crypt_wq, &wg->decrypt_queue.last_cpu);
|
||||
if (unlikely(ret == -EPIPE))
|
||||
- wg_queue_enqueue_per_peer_napi(skb, PACKET_STATE_DEAD);
|
||||
+ wg_queue_enqueue_per_peer_rx(skb, PACKET_STATE_DEAD);
|
||||
if (likely(!ret || ret == -EPIPE)) {
|
||||
rcu_read_unlock_bh();
|
||||
return;
|
||||
--- a/drivers/net/wireguard/send.c
|
||||
+++ b/drivers/net/wireguard/send.c
|
||||
@@ -239,8 +239,7 @@ void wg_packet_send_keepalive(struct wg_
|
||||
wg_packet_send_staged_packets(peer);
|
||||
}
|
||||
|
||||
-static void wg_packet_create_data_done(struct sk_buff *first,
|
||||
- struct wg_peer *peer)
|
||||
+static void wg_packet_create_data_done(struct wg_peer *peer, struct sk_buff *first)
|
||||
{
|
||||
struct sk_buff *skb, *next;
|
||||
bool is_keepalive, data_sent = false;
|
||||
@@ -262,22 +261,19 @@ static void wg_packet_create_data_done(s
|
||||
|
||||
void wg_packet_tx_worker(struct work_struct *work)
|
||||
{
|
||||
- struct crypt_queue *queue = container_of(work, struct crypt_queue,
|
||||
- work);
|
||||
+ struct wg_peer *peer = container_of(work, struct wg_peer, transmit_packet_work);
|
||||
struct noise_keypair *keypair;
|
||||
enum packet_state state;
|
||||
struct sk_buff *first;
|
||||
- struct wg_peer *peer;
|
||||
|
||||
- while ((first = __ptr_ring_peek(&queue->ring)) != NULL &&
|
||||
+ while ((first = wg_prev_queue_peek(&peer->tx_queue)) != NULL &&
|
||||
(state = atomic_read_acquire(&PACKET_CB(first)->state)) !=
|
||||
PACKET_STATE_UNCRYPTED) {
|
||||
- __ptr_ring_discard_one(&queue->ring);
|
||||
- peer = PACKET_PEER(first);
|
||||
+ wg_prev_queue_drop_peeked(&peer->tx_queue);
|
||||
keypair = PACKET_CB(first)->keypair;
|
||||
|
||||
if (likely(state == PACKET_STATE_CRYPTED))
|
||||
- wg_packet_create_data_done(first, peer);
|
||||
+ wg_packet_create_data_done(peer, first);
|
||||
else
|
||||
kfree_skb_list(first);
|
||||
|
||||
@@ -306,16 +302,14 @@ void wg_packet_encrypt_worker(struct wor
|
||||
break;
|
||||
}
|
||||
}
|
||||
- wg_queue_enqueue_per_peer(&PACKET_PEER(first)->tx_queue, first,
|
||||
- state);
|
||||
+ wg_queue_enqueue_per_peer_tx(first, state);
|
||||
if (need_resched())
|
||||
cond_resched();
|
||||
}
|
||||
}
|
||||
|
||||
-static void wg_packet_create_data(struct sk_buff *first)
|
||||
+static void wg_packet_create_data(struct wg_peer *peer, struct sk_buff *first)
|
||||
{
|
||||
- struct wg_peer *peer = PACKET_PEER(first);
|
||||
struct wg_device *wg = peer->device;
|
||||
int ret = -EINVAL;
|
||||
|
||||
@@ -323,13 +317,10 @@ static void wg_packet_create_data(struct
|
||||
if (unlikely(READ_ONCE(peer->is_dead)))
|
||||
goto err;
|
||||
|
||||
- ret = wg_queue_enqueue_per_device_and_peer(&wg->encrypt_queue,
|
||||
- &peer->tx_queue, first,
|
||||
- wg->packet_crypt_wq,
|
||||
- &wg->encrypt_queue.last_cpu);
|
||||
+ ret = wg_queue_enqueue_per_device_and_peer(&wg->encrypt_queue, &peer->tx_queue, first,
|
||||
+ wg->packet_crypt_wq, &wg->encrypt_queue.last_cpu);
|
||||
if (unlikely(ret == -EPIPE))
|
||||
- wg_queue_enqueue_per_peer(&peer->tx_queue, first,
|
||||
- PACKET_STATE_DEAD);
|
||||
+ wg_queue_enqueue_per_peer_tx(first, PACKET_STATE_DEAD);
|
||||
err:
|
||||
rcu_read_unlock_bh();
|
||||
if (likely(!ret || ret == -EPIPE))
|
||||
@@ -393,7 +384,7 @@ void wg_packet_send_staged_packets(struc
|
||||
packets.prev->next = NULL;
|
||||
wg_peer_get(keypair->entry.peer);
|
||||
PACKET_CB(packets.next)->keypair = keypair;
|
||||
- wg_packet_create_data(packets.next);
|
||||
+ wg_packet_create_data(peer, packets.next);
|
||||
return;
|
||||
|
||||
out_invalid:
|
@ -1,30 +0,0 @@
|
||||
From 514091206bc055a159348ae8575276dc925aea24 Mon Sep 17 00:00:00 2001
|
||||
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
|
||||
Date: Mon, 22 Feb 2021 17:25:49 +0100
|
||||
Subject: [PATCH] wireguard: kconfig: use arm chacha even with no neon
|
||||
|
||||
commit bce2473927af8de12ad131a743f55d69d358c0b9 upstream.
|
||||
|
||||
The condition here was incorrect: a non-neon fallback implementation is
|
||||
available on arm32 when NEON is not supported.
|
||||
|
||||
Reported-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
|
||||
Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
|
||||
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
||||
---
|
||||
drivers/net/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/Kconfig
|
||||
+++ b/drivers/net/Kconfig
|
||||
@@ -87,7 +87,7 @@ config WIREGUARD
|
||||
select CRYPTO_CURVE25519_X86 if X86 && 64BIT
|
||||
select ARM_CRYPTO if ARM
|
||||
select ARM64_CRYPTO if ARM64
|
||||
- select CRYPTO_CHACHA20_NEON if (ARM || ARM64) && KERNEL_MODE_NEON
|
||||
+ select CRYPTO_CHACHA20_NEON if ARM || (ARM64 && KERNEL_MODE_NEON)
|
||||
select CRYPTO_POLY1305_NEON if ARM64 && KERNEL_MODE_NEON
|
||||
select CRYPTO_POLY1305_ARM if ARM
|
||||
select CRYPTO_CURVE25519_NEON if ARM && KERNEL_MODE_NEON
|
@ -1,73 +0,0 @@
|
||||
From 6420a569504e212d618d4a4736e2c59ed80a8478 Mon Sep 17 00:00:00 2001
|
||||
From: Lech Perczak <lech.perczak@gmail.com>
|
||||
Date: Sun, 7 Feb 2021 01:54:43 +0100
|
||||
Subject: USB: serial: option: update interface mapping for ZTE P685M
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This patch prepares for qmi_wwan driver support for the device.
|
||||
Previously "option" driver mapped itself to interfaces 0 and 3 (matching
|
||||
ff/ff/ff), while interface 3 is in fact a QMI port.
|
||||
Interfaces 1 and 2 (matching ff/00/00) expose AT commands,
|
||||
and weren't supported previously at all.
|
||||
Without this patch, a possible conflict would exist if device ID was
|
||||
added to qmi_wwan driver for interface 3.
|
||||
|
||||
Update and simplify device ID to match interfaces 0-2 directly,
|
||||
to expose QCDM (0), PCUI (1), and modem (2) ports and avoid conflict
|
||||
with QMI (3), and ADB (4).
|
||||
|
||||
The modem is used inside ZTE MF283+ router and carriers identify it as
|
||||
such.
|
||||
Interface mapping is:
|
||||
0: QCDM, 1: AT (PCUI), 2: AT (Modem), 3: QMI, 4: ADB
|
||||
|
||||
T: Bus=02 Lev=02 Prnt=02 Port=05 Cnt=01 Dev#= 3 Spd=480 MxCh= 0
|
||||
D: Ver= 2.01 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
|
||||
P: Vendor=19d2 ProdID=1275 Rev=f0.00
|
||||
S: Manufacturer=ZTE,Incorporated
|
||||
S: Product=ZTE Technologies MSM
|
||||
S: SerialNumber=P685M510ZTED0000CP&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&0
|
||||
C:* #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=500mA
|
||||
I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
|
||||
E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
|
||||
E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
|
||||
I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
|
||||
E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
|
||||
E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
|
||||
E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
|
||||
I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
|
||||
E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
|
||||
E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
|
||||
E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
|
||||
I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
|
||||
E: Ad=87(I) Atr=03(Int.) MxPS= 8 Ivl=32ms
|
||||
E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
|
||||
E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
|
||||
I:* If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)
|
||||
E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
|
||||
E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
|
||||
|
||||
Cc: Johan Hovold <johan@kernel.org>
|
||||
Cc: Bjørn Mork <bjorn@mork.no>
|
||||
Signed-off-by: Lech Perczak <lech.perczak@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20210207005443.12936-1-lech.perczak@gmail.com
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Johan Hovold <johan@kernel.org>
|
||||
---
|
||||
drivers/usb/serial/option.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/usb/serial/option.c
|
||||
+++ b/drivers/usb/serial/option.c
|
||||
@@ -1569,7 +1569,8 @@ static const struct usb_device_id option
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1272, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1273, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1274, 0xff, 0xff, 0xff) },
|
||||
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1275, 0xff, 0xff, 0xff) },
|
||||
+ { USB_DEVICE(ZTE_VENDOR_ID, 0x1275), /* ZTE P685M */
|
||||
+ .driver_info = RSVD(3) | RSVD(4) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1276, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1277, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1278, 0xff, 0xff, 0xff) },
|
@ -1,148 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
|
||||
Date: Tue, 11 Feb 2020 20:47:05 +0100
|
||||
Subject: [PATCH] icmp: introduce helper for nat'd source address in network
|
||||
device context
|
||||
|
||||
commit 0b41713b606694257b90d61ba7e2712d8457648b upstream.
|
||||
|
||||
This introduces a helper function to be called only by network drivers
|
||||
that wraps calls to icmp[v6]_send in a conntrack transformation, in case
|
||||
NAT has been used. We don't want to pollute the non-driver path, though,
|
||||
so we introduce this as a helper to be called by places that actually
|
||||
make use of this, as suggested by Florian.
|
||||
|
||||
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
||||
Cc: Florian Westphal <fw@strlen.de>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
||||
---
|
||||
include/linux/icmpv6.h | 10 ++++++++++
|
||||
include/net/icmp.h | 6 ++++++
|
||||
net/ipv4/icmp.c | 33 +++++++++++++++++++++++++++++++++
|
||||
net/ipv6/ip6_icmp.c | 34 ++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 83 insertions(+)
|
||||
|
||||
--- a/include/linux/icmpv6.h
|
||||
+++ b/include/linux/icmpv6.h
|
||||
@@ -22,12 +22,22 @@ extern int inet6_unregister_icmp_sender(
|
||||
int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
|
||||
unsigned int data_len);
|
||||
|
||||
+#if IS_ENABLED(CONFIG_NF_NAT)
|
||||
+void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info);
|
||||
+#else
|
||||
+#define icmpv6_ndo_send icmpv6_send
|
||||
+#endif
|
||||
+
|
||||
#else
|
||||
|
||||
static inline void icmpv6_send(struct sk_buff *skb,
|
||||
u8 type, u8 code, __u32 info)
|
||||
{
|
||||
+}
|
||||
|
||||
+static inline void icmpv6_ndo_send(struct sk_buff *skb,
|
||||
+ u8 type, u8 code, __u32 info)
|
||||
+{
|
||||
}
|
||||
#endif
|
||||
|
||||
--- a/include/net/icmp.h
|
||||
+++ b/include/net/icmp.h
|
||||
@@ -43,6 +43,12 @@ static inline void icmp_send(struct sk_b
|
||||
__icmp_send(skb_in, type, code, info, &IPCB(skb_in)->opt);
|
||||
}
|
||||
|
||||
+#if IS_ENABLED(CONFIG_NF_NAT)
|
||||
+void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info);
|
||||
+#else
|
||||
+#define icmp_ndo_send icmp_send
|
||||
+#endif
|
||||
+
|
||||
int icmp_rcv(struct sk_buff *skb);
|
||||
int icmp_err(struct sk_buff *skb, u32 info);
|
||||
int icmp_init(void);
|
||||
--- a/net/ipv4/icmp.c
|
||||
+++ b/net/ipv4/icmp.c
|
||||
@@ -750,6 +750,39 @@ out:;
|
||||
}
|
||||
EXPORT_SYMBOL(__icmp_send);
|
||||
|
||||
+#if IS_ENABLED(CONFIG_NF_NAT)
|
||||
+#include <net/netfilter/nf_conntrack.h>
|
||||
+void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info)
|
||||
+{
|
||||
+ struct sk_buff *cloned_skb = NULL;
|
||||
+ enum ip_conntrack_info ctinfo;
|
||||
+ struct nf_conn *ct;
|
||||
+ __be32 orig_ip;
|
||||
+
|
||||
+ ct = nf_ct_get(skb_in, &ctinfo);
|
||||
+ if (!ct || !(ct->status & IPS_SRC_NAT)) {
|
||||
+ icmp_send(skb_in, type, code, info);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (skb_shared(skb_in))
|
||||
+ skb_in = cloned_skb = skb_clone(skb_in, GFP_ATOMIC);
|
||||
+
|
||||
+ if (unlikely(!skb_in || skb_network_header(skb_in) < skb_in->head ||
|
||||
+ (skb_network_header(skb_in) + sizeof(struct iphdr)) >
|
||||
+ skb_tail_pointer(skb_in) || skb_ensure_writable(skb_in,
|
||||
+ skb_network_offset(skb_in) + sizeof(struct iphdr))))
|
||||
+ goto out;
|
||||
+
|
||||
+ orig_ip = ip_hdr(skb_in)->saddr;
|
||||
+ ip_hdr(skb_in)->saddr = ct->tuplehash[0].tuple.src.u3.ip;
|
||||
+ icmp_send(skb_in, type, code, info);
|
||||
+ ip_hdr(skb_in)->saddr = orig_ip;
|
||||
+out:
|
||||
+ consume_skb(cloned_skb);
|
||||
+}
|
||||
+EXPORT_SYMBOL(icmp_ndo_send);
|
||||
+#endif
|
||||
|
||||
static void icmp_socket_deliver(struct sk_buff *skb, u32 info)
|
||||
{
|
||||
--- a/net/ipv6/ip6_icmp.c
|
||||
+++ b/net/ipv6/ip6_icmp.c
|
||||
@@ -45,4 +45,38 @@ out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL(icmpv6_send);
|
||||
+
|
||||
+#if IS_ENABLED(CONFIG_NF_NAT)
|
||||
+#include <net/netfilter/nf_conntrack.h>
|
||||
+void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info)
|
||||
+{
|
||||
+ struct sk_buff *cloned_skb = NULL;
|
||||
+ enum ip_conntrack_info ctinfo;
|
||||
+ struct in6_addr orig_ip;
|
||||
+ struct nf_conn *ct;
|
||||
+
|
||||
+ ct = nf_ct_get(skb_in, &ctinfo);
|
||||
+ if (!ct || !(ct->status & IPS_SRC_NAT)) {
|
||||
+ icmpv6_send(skb_in, type, code, info);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (skb_shared(skb_in))
|
||||
+ skb_in = cloned_skb = skb_clone(skb_in, GFP_ATOMIC);
|
||||
+
|
||||
+ if (unlikely(!skb_in || skb_network_header(skb_in) < skb_in->head ||
|
||||
+ (skb_network_header(skb_in) + sizeof(struct ipv6hdr)) >
|
||||
+ skb_tail_pointer(skb_in) || skb_ensure_writable(skb_in,
|
||||
+ skb_network_offset(skb_in) + sizeof(struct ipv6hdr))))
|
||||
+ goto out;
|
||||
+
|
||||
+ orig_ip = ipv6_hdr(skb_in)->saddr;
|
||||
+ ipv6_hdr(skb_in)->saddr = ct->tuplehash[0].tuple.src.u3.in6;
|
||||
+ icmpv6_send(skb_in, type, code, info);
|
||||
+ ipv6_hdr(skb_in)->saddr = orig_ip;
|
||||
+out:
|
||||
+ consume_skb(cloned_skb);
|
||||
+}
|
||||
+EXPORT_SYMBOL(icmpv6_ndo_send);
|
||||
+#endif
|
||||
#endif
|
@ -1,299 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
|
||||
Date: Tue, 23 Feb 2021 14:18:58 +0100
|
||||
Subject: [PATCH] net: icmp: pass zeroed opts from icmp{,v6}_ndo_send before
|
||||
sending
|
||||
|
||||
commit ee576c47db60432c37e54b1e2b43a8ca6d3a8dca upstream.
|
||||
|
||||
The icmp{,v6}_send functions make all sorts of use of skb->cb, casting
|
||||
it with IPCB or IP6CB, assuming the skb to have come directly from the
|
||||
inet layer. But when the packet comes from the ndo layer, especially
|
||||
when forwarded, there's no telling what might be in skb->cb at that
|
||||
point. As a result, the icmp sending code risks reading bogus memory
|
||||
contents, which can result in nasty stack overflows such as this one
|
||||
reported by a user:
|
||||
|
||||
panic+0x108/0x2ea
|
||||
__stack_chk_fail+0x14/0x20
|
||||
__icmp_send+0x5bd/0x5c0
|
||||
icmp_ndo_send+0x148/0x160
|
||||
|
||||
In icmp_send, skb->cb is cast with IPCB and an ip_options struct is read
|
||||
from it. The optlen parameter there is of particular note, as it can
|
||||
induce writes beyond bounds. There are quite a few ways that can happen
|
||||
in __ip_options_echo. For example:
|
||||
|
||||
// sptr/skb are attacker-controlled skb bytes
|
||||
sptr = skb_network_header(skb);
|
||||
// dptr/dopt points to stack memory allocated by __icmp_send
|
||||
dptr = dopt->__data;
|
||||
// sopt is the corrupt skb->cb in question
|
||||
if (sopt->rr) {
|
||||
optlen = sptr[sopt->rr+1]; // corrupt skb->cb + skb->data
|
||||
soffset = sptr[sopt->rr+2]; // corrupt skb->cb + skb->data
|
||||
// this now writes potentially attacker-controlled data, over
|
||||
// flowing the stack:
|
||||
memcpy(dptr, sptr+sopt->rr, optlen);
|
||||
}
|
||||
|
||||
In the icmpv6_send case, the story is similar, but not as dire, as only
|
||||
IP6CB(skb)->iif and IP6CB(skb)->dsthao are used. The dsthao case is
|
||||
worse than the iif case, but it is passed to ipv6_find_tlv, which does
|
||||
a bit of bounds checking on the value.
|
||||
|
||||
This is easy to simulate by doing a `memset(skb->cb, 0x41,
|
||||
sizeof(skb->cb));` before calling icmp{,v6}_ndo_send, and it's only by
|
||||
good fortune and the rarity of icmp sending from that context that we've
|
||||
avoided reports like this until now. For example, in KASAN:
|
||||
|
||||
BUG: KASAN: stack-out-of-bounds in __ip_options_echo+0xa0e/0x12b0
|
||||
Write of size 38 at addr ffff888006f1f80e by task ping/89
|
||||
CPU: 2 PID: 89 Comm: ping Not tainted 5.10.0-rc7-debug+ #5
|
||||
Call Trace:
|
||||
dump_stack+0x9a/0xcc
|
||||
print_address_description.constprop.0+0x1a/0x160
|
||||
__kasan_report.cold+0x20/0x38
|
||||
kasan_report+0x32/0x40
|
||||
check_memory_region+0x145/0x1a0
|
||||
memcpy+0x39/0x60
|
||||
__ip_options_echo+0xa0e/0x12b0
|
||||
__icmp_send+0x744/0x1700
|
||||
|
||||
Actually, out of the 4 drivers that do this, only gtp zeroed the cb for
|
||||
the v4 case, while the rest did not. So this commit actually removes the
|
||||
gtp-specific zeroing, while putting the code where it belongs in the
|
||||
shared infrastructure of icmp{,v6}_ndo_send.
|
||||
|
||||
This commit fixes the issue by passing an empty IPCB or IP6CB along to
|
||||
the functions that actually do the work. For the icmp_send, this was
|
||||
already trivial, thanks to __icmp_send providing the plumbing function.
|
||||
For icmpv6_send, this required a tiny bit of refactoring to make it
|
||||
behave like the v4 case, after which it was straight forward.
|
||||
|
||||
Fixes: a2b78e9b2cac ("sunvnet: generate ICMP PTMUD messages for smaller port MTUs")
|
||||
Reported-by: SinYu <liuxyon@gmail.com>
|
||||
Reviewed-by: Willem de Bruijn <willemb@google.com>
|
||||
Link: https://lore.kernel.org/netdev/CAF=yD-LOF116aHub6RMe8vB8ZpnrrnoTdqhobEx+bvoA8AsP0w@mail.gmail.com/T/
|
||||
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
||||
Link: https://lore.kernel.org/r/20210223131858.72082-1-Jason@zx2c4.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
[Jason: the gtp part didn't apply because it doesn't use icmp_ndo_send on 5.4]
|
||||
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
||||
---
|
||||
include/linux/icmpv6.h | 17 ++++++++++++++---
|
||||
include/linux/ipv6.h | 1 -
|
||||
include/net/icmp.h | 6 +++++-
|
||||
net/ipv4/icmp.c | 5 +++--
|
||||
net/ipv6/icmp.c | 16 ++++++++--------
|
||||
net/ipv6/ip6_icmp.c | 12 +++++++-----
|
||||
6 files changed, 37 insertions(+), 20 deletions(-)
|
||||
|
||||
--- a/include/linux/icmpv6.h
|
||||
+++ b/include/linux/icmpv6.h
|
||||
@@ -3,6 +3,7 @@
|
||||
#define _LINUX_ICMPV6_H
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
+#include <linux/ipv6.h>
|
||||
#include <uapi/linux/icmpv6.h>
|
||||
|
||||
static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff *skb)
|
||||
@@ -13,10 +14,16 @@ static inline struct icmp6hdr *icmp6_hdr
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
-extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info);
|
||||
+extern void __icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
|
||||
+ const struct inet6_skb_parm *parm);
|
||||
|
||||
+static inline void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
|
||||
+{
|
||||
+ __icmpv6_send(skb, type, code, info, IP6CB(skb));
|
||||
+}
|
||||
typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info,
|
||||
- const struct in6_addr *force_saddr);
|
||||
+ const struct in6_addr *force_saddr,
|
||||
+ const struct inet6_skb_parm *parm);
|
||||
extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
|
||||
extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
|
||||
int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
|
||||
@@ -25,7 +32,11 @@ int ip6_err_gen_icmpv6_unreach(struct sk
|
||||
#if IS_ENABLED(CONFIG_NF_NAT)
|
||||
void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info);
|
||||
#else
|
||||
-#define icmpv6_ndo_send icmpv6_send
|
||||
+static inline void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info)
|
||||
+{
|
||||
+ struct inet6_skb_parm parm = { 0 };
|
||||
+ __icmpv6_send(skb_in, type, code, info, &parm);
|
||||
+}
|
||||
#endif
|
||||
|
||||
#else
|
||||
--- a/include/linux/ipv6.h
|
||||
+++ b/include/linux/ipv6.h
|
||||
@@ -83,7 +83,6 @@ struct ipv6_params {
|
||||
__s32 autoconf;
|
||||
};
|
||||
extern struct ipv6_params ipv6_defaults;
|
||||
-#include <linux/icmpv6.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/udp.h>
|
||||
|
||||
--- a/include/net/icmp.h
|
||||
+++ b/include/net/icmp.h
|
||||
@@ -46,7 +46,11 @@ static inline void icmp_send(struct sk_b
|
||||
#if IS_ENABLED(CONFIG_NF_NAT)
|
||||
void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info);
|
||||
#else
|
||||
-#define icmp_ndo_send icmp_send
|
||||
+static inline void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info)
|
||||
+{
|
||||
+ struct ip_options opts = { 0 };
|
||||
+ __icmp_send(skb_in, type, code, info, &opts);
|
||||
+}
|
||||
#endif
|
||||
|
||||
int icmp_rcv(struct sk_buff *skb);
|
||||
--- a/net/ipv4/icmp.c
|
||||
+++ b/net/ipv4/icmp.c
|
||||
@@ -755,13 +755,14 @@ EXPORT_SYMBOL(__icmp_send);
|
||||
void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info)
|
||||
{
|
||||
struct sk_buff *cloned_skb = NULL;
|
||||
+ struct ip_options opts = { 0 };
|
||||
enum ip_conntrack_info ctinfo;
|
||||
struct nf_conn *ct;
|
||||
__be32 orig_ip;
|
||||
|
||||
ct = nf_ct_get(skb_in, &ctinfo);
|
||||
if (!ct || !(ct->status & IPS_SRC_NAT)) {
|
||||
- icmp_send(skb_in, type, code, info);
|
||||
+ __icmp_send(skb_in, type, code, info, &opts);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -776,7 +777,7 @@ void icmp_ndo_send(struct sk_buff *skb_i
|
||||
|
||||
orig_ip = ip_hdr(skb_in)->saddr;
|
||||
ip_hdr(skb_in)->saddr = ct->tuplehash[0].tuple.src.u3.ip;
|
||||
- icmp_send(skb_in, type, code, info);
|
||||
+ __icmp_send(skb_in, type, code, info, &opts);
|
||||
ip_hdr(skb_in)->saddr = orig_ip;
|
||||
out:
|
||||
consume_skb(cloned_skb);
|
||||
--- a/net/ipv6/icmp.c
|
||||
+++ b/net/ipv6/icmp.c
|
||||
@@ -312,10 +312,9 @@ static int icmpv6_getfrag(void *from, ch
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6_MIP6)
|
||||
-static void mip6_addr_swap(struct sk_buff *skb)
|
||||
+static void mip6_addr_swap(struct sk_buff *skb, const struct inet6_skb_parm *opt)
|
||||
{
|
||||
struct ipv6hdr *iph = ipv6_hdr(skb);
|
||||
- struct inet6_skb_parm *opt = IP6CB(skb);
|
||||
struct ipv6_destopt_hao *hao;
|
||||
struct in6_addr tmp;
|
||||
int off;
|
||||
@@ -332,7 +331,7 @@ static void mip6_addr_swap(struct sk_buf
|
||||
}
|
||||
}
|
||||
#else
|
||||
-static inline void mip6_addr_swap(struct sk_buff *skb) {}
|
||||
+static inline void mip6_addr_swap(struct sk_buff *skb, const struct inet6_skb_parm *opt) {}
|
||||
#endif
|
||||
|
||||
static struct dst_entry *icmpv6_route_lookup(struct net *net,
|
||||
@@ -427,7 +426,8 @@ static int icmp6_iif(const struct sk_buf
|
||||
* Send an ICMP message in response to a packet in error
|
||||
*/
|
||||
static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
|
||||
- const struct in6_addr *force_saddr)
|
||||
+ const struct in6_addr *force_saddr,
|
||||
+ const struct inet6_skb_parm *parm)
|
||||
{
|
||||
struct inet6_dev *idev = NULL;
|
||||
struct ipv6hdr *hdr = ipv6_hdr(skb);
|
||||
@@ -520,7 +520,7 @@ static void icmp6_send(struct sk_buff *s
|
||||
if (!(skb->dev->flags & IFF_LOOPBACK) && !icmpv6_global_allow(net, type))
|
||||
goto out_bh_enable;
|
||||
|
||||
- mip6_addr_swap(skb);
|
||||
+ mip6_addr_swap(skb, parm);
|
||||
|
||||
memset(&fl6, 0, sizeof(fl6));
|
||||
fl6.flowi6_proto = IPPROTO_ICMPV6;
|
||||
@@ -605,7 +605,7 @@ out_bh_enable:
|
||||
*/
|
||||
void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
|
||||
{
|
||||
- icmp6_send(skb, ICMPV6_PARAMPROB, code, pos, NULL);
|
||||
+ icmp6_send(skb, ICMPV6_PARAMPROB, code, pos, NULL, IP6CB(skb));
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
@@ -662,10 +662,10 @@ int ip6_err_gen_icmpv6_unreach(struct sk
|
||||
}
|
||||
if (type == ICMP_TIME_EXCEEDED)
|
||||
icmp6_send(skb2, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
|
||||
- info, &temp_saddr);
|
||||
+ info, &temp_saddr, IP6CB(skb2));
|
||||
else
|
||||
icmp6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH,
|
||||
- info, &temp_saddr);
|
||||
+ info, &temp_saddr, IP6CB(skb2));
|
||||
if (rt)
|
||||
ip6_rt_put(rt);
|
||||
|
||||
--- a/net/ipv6/ip6_icmp.c
|
||||
+++ b/net/ipv6/ip6_icmp.c
|
||||
@@ -31,7 +31,8 @@ int inet6_unregister_icmp_sender(ip6_icm
|
||||
}
|
||||
EXPORT_SYMBOL(inet6_unregister_icmp_sender);
|
||||
|
||||
-void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
|
||||
+void __icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
|
||||
+ const struct inet6_skb_parm *parm)
|
||||
{
|
||||
ip6_icmp_send_t *send;
|
||||
|
||||
@@ -40,16 +41,17 @@ void icmpv6_send(struct sk_buff *skb, u8
|
||||
|
||||
if (!send)
|
||||
goto out;
|
||||
- send(skb, type, code, info, NULL);
|
||||
+ send(skb, type, code, info, NULL, parm);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
-EXPORT_SYMBOL(icmpv6_send);
|
||||
+EXPORT_SYMBOL(__icmpv6_send);
|
||||
|
||||
#if IS_ENABLED(CONFIG_NF_NAT)
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info)
|
||||
{
|
||||
+ struct inet6_skb_parm parm = { 0 };
|
||||
struct sk_buff *cloned_skb = NULL;
|
||||
enum ip_conntrack_info ctinfo;
|
||||
struct in6_addr orig_ip;
|
||||
@@ -57,7 +59,7 @@ void icmpv6_ndo_send(struct sk_buff *skb
|
||||
|
||||
ct = nf_ct_get(skb_in, &ctinfo);
|
||||
if (!ct || !(ct->status & IPS_SRC_NAT)) {
|
||||
- icmpv6_send(skb_in, type, code, info);
|
||||
+ __icmpv6_send(skb_in, type, code, info, &parm);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -72,7 +74,7 @@ void icmpv6_ndo_send(struct sk_buff *skb
|
||||
|
||||
orig_ip = ipv6_hdr(skb_in)->saddr;
|
||||
ipv6_hdr(skb_in)->saddr = ct->tuplehash[0].tuple.src.u3.in6;
|
||||
- icmpv6_send(skb_in, type, code, info);
|
||||
+ __icmpv6_send(skb_in, type, code, info, &parm);
|
||||
ipv6_hdr(skb_in)->saddr = orig_ip;
|
||||
out:
|
||||
consume_skb(cloned_skb);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user