4330 lines
153 KiB
Diff
4330 lines
153 KiB
Diff
diff --git a/package/kernel/linux/modules/crypto.mk b/package/kernel/linux/modules/crypto.mk
|
|
index dc7eb77986..60267f3c8e 100644
|
|
--- a/package/kernel/linux/modules/crypto.mk
|
|
+++ b/package/kernel/linux/modules/crypto.mk
|
|
@@ -110,8 +110,8 @@ define KernelPackage/crypto-crc32
|
|
DEPENDS:=+kmod-crypto-hash
|
|
KCONFIG:=CONFIG_CRYPTO_CRC32
|
|
HIDDEN:=1
|
|
- FILES:=$(LINUX_DIR)/crypto/crc32_generic.ko@ge4.9
|
|
- AUTOLOAD:=$(call AutoLoad,04,crc32_generic@ge4.9,1)
|
|
+ FILES:=$(LINUX_DIR)/crypto/crc32_generic.ko
|
|
+ AUTOLOAD:=$(call AutoLoad,04,crc32_generic,1)
|
|
$(call AddDepends/crypto)
|
|
endef
|
|
|
|
@@ -169,7 +169,9 @@ $(eval $(call KernelPackage,crypto-deflate))
|
|
define KernelPackage/crypto-des
|
|
TITLE:=DES/3DES cipher CryptoAPI module
|
|
KCONFIG:=CONFIG_CRYPTO_DES
|
|
- FILES:=$(LINUX_DIR)/crypto/des_generic.ko
|
|
+ FILES:= \
|
|
+ $(LINUX_DIR)/crypto/des_generic.ko \
|
|
+ $(LINUX_DIR)/lib/crypto/libdes.ko@ge5.4
|
|
AUTOLOAD:=$(call AutoLoad,09,des_generic)
|
|
$(call AddDepends/crypto)
|
|
endef
|
|
@@ -194,7 +196,8 @@ define KernelPackage/crypto-ecdh
|
|
DEPENDS:=+kmod-crypto-kpp
|
|
KCONFIG:= CONFIG_CRYPTO_ECDH
|
|
FILES:= \
|
|
- $(LINUX_DIR)/crypto/ecdh_generic.ko
|
|
+ $(LINUX_DIR)/crypto/ecdh_generic.ko \
|
|
+ $(LINUX_DIR)/crypto/ecc.ko@ge5.2
|
|
AUTOLOAD:=$(call AutoLoad,10,ecdh_generic)
|
|
$(call AddDepends/crypto)
|
|
endef
|
|
@@ -263,12 +266,23 @@ $(eval $(call KernelPackage,crypto-gf128))
|
|
define KernelPackage/crypto-ghash
|
|
TITLE:=GHASH digest CryptoAPI module
|
|
DEPENDS:=+kmod-crypto-gf128 +kmod-crypto-hash
|
|
- KCONFIG:=CONFIG_CRYPTO_GHASH
|
|
+ KCONFIG:= \
|
|
+ CONFIG_CRYPTO_GHASH \
|
|
+ CONFIG_CRYPTO_GHASH_ARM_CE
|
|
FILES:=$(LINUX_DIR)/crypto/ghash-generic.ko
|
|
AUTOLOAD:=$(call AutoLoad,09,ghash-generic)
|
|
$(call AddDepends/crypto)
|
|
endef
|
|
|
|
+define KernelPackage/crypto-ghash/arm-ce
|
|
+ FILES+= $(LINUX_DIR)/arch/arm/crypto/ghash-arm-ce.ko
|
|
+ AUTOLOAD+=$(call AutoLoad,09,ghash-arm-ce)
|
|
+endef
|
|
+
|
|
+KernelPackage/crypto-ghash/imx6=$(KernelPackage/crypto-ghash/arm-ce)
|
|
+KernelPackage/crypto-ghash/ipq40xx=$(KernelPackage/crypto-ghash/arm-ce)
|
|
+KernelPackage/crypto-ghash/mvebu=$(KernelPackage/crypto-ghash/arm-ce)
|
|
+
|
|
$(eval $(call KernelPackage,crypto-ghash))
|
|
|
|
|
|
@@ -402,7 +416,6 @@ endef
|
|
|
|
$(eval $(call KernelPackage,crypto-hw-talitos))
|
|
|
|
-
|
|
define KernelPackage/crypto-iv
|
|
TITLE:=CryptoAPI initialization vectors
|
|
DEPENDS:=+kmod-crypto-manager +kmod-crypto-rng +kmod-crypto-wq
|
|
@@ -417,7 +430,6 @@ endef
|
|
|
|
$(eval $(call KernelPackage,crypto-iv))
|
|
|
|
-
|
|
define KernelPackage/crypto-kpp
|
|
TITLE:=Key-agreement Protocol Primitives
|
|
KCONFIG:=CONFIG_CRYPTO_KPP
|
|
@@ -656,11 +668,10 @@ define KernelPackage/crypto-rng
|
|
CONFIG_CRYPTO_JITTERENTROPY \
|
|
CONFIG_CRYPTO_RNG2
|
|
FILES:= \
|
|
- $(LINUX_DIR)/crypto/drbg.ko@ge4.2 \
|
|
- $(LINUX_DIR)/crypto/jitterentropy_rng.ko@ge4.2 \
|
|
- $(LINUX_DIR)/crypto/krng.ko@lt4.2 \
|
|
+ $(LINUX_DIR)/crypto/drbg.ko \
|
|
+ $(LINUX_DIR)/crypto/jitterentropy_rng.ko \
|
|
$(LINUX_DIR)/crypto/rng.ko
|
|
- AUTOLOAD:=$(call AutoLoad,09,drbg@ge4.2 jitterentropy_rng@ge4.2 krng@lt4.2 rng)
|
|
+ AUTOLOAD:=$(call AutoLoad,09,drbg jitterentropy_rng rng)
|
|
$(call AddDepends/crypto)
|
|
endef
|
|
|
|
@@ -684,6 +695,8 @@ define KernelPackage/crypto-sha1
|
|
DEPENDS:=+kmod-crypto-hash
|
|
KCONFIG:= \
|
|
CONFIG_CRYPTO_SHA1 \
|
|
+ CONFIG_CRYPTO_SHA1_ARM \
|
|
+ CONFIG_CRYPTO_SHA1_ARM_NEON \
|
|
CONFIG_CRYPTO_SHA1_OCTEON \
|
|
CONFIG_CRYPTO_SHA1_SSSE3
|
|
FILES:=$(LINUX_DIR)/crypto/sha1_generic.ko
|
|
@@ -691,11 +704,28 @@ define KernelPackage/crypto-sha1
|
|
$(call AddDepends/crypto)
|
|
endef
|
|
|
|
+define KernelPackage/crypto-sha1/arm
|
|
+ FILES+=$(LINUX_DIR)/arch/arm/crypto/sha1-arm.ko
|
|
+ AUTOLOAD+=$(call AutoLoad,09,sha1-arm)
|
|
+endef
|
|
+
|
|
+define KernelPackage/crypto-sha1/arm-neon
|
|
+ $(call KernelPackage/crypto-sha1/arm)
|
|
+ FILES+=$(LINUX_DIR)/arch/arm/crypto/sha1-arm-neon.ko
|
|
+ AUTOLOAD+=$(call AutoLoad,09,sha1-arm-neon)
|
|
+endef
|
|
+
|
|
+KernelPackage/crypto-sha1/imx6=$(KernelPackage/crypto-sha1/arm-neon)
|
|
+KernelPackage/crypto-sha1/ipq40xx=$(KernelPackage/crypto-sha1/arm-neon)
|
|
+KernelPackage/crypto-sha1/mvebu/cortexa9=$(KernelPackage/crypto-sha1/arm-neon)
|
|
+
|
|
define KernelPackage/crypto-sha1/octeon
|
|
FILES+=$(LINUX_DIR)/arch/mips/cavium-octeon/crypto/octeon-sha1.ko
|
|
AUTOLOAD+=$(call AutoLoad,09,octeon-sha1)
|
|
endef
|
|
|
|
+KernelPackage/crypto-sha1/tegra=$(KernelPakcage/crypto-sha1/arm)
|
|
+
|
|
define KernelPackage/crypto-sha1/x86/64
|
|
FILES+=$(LINUX_DIR)/arch/x86/crypto/sha1-ssse3.ko
|
|
AUTOLOAD+=$(call AutoLoad,09,sha1-ssse3)
|
|
@@ -711,7 +741,9 @@ define KernelPackage/crypto-sha256
|
|
CONFIG_CRYPTO_SHA256 \
|
|
CONFIG_CRYPTO_SHA256_OCTEON \
|
|
CONFIG_CRYPTO_SHA256_SSSE3
|
|
- FILES:=$(LINUX_DIR)/crypto/sha256_generic.ko
|
|
+ FILES:= \
|
|
+ $(LINUX_DIR)/crypto/sha256_generic.ko \
|
|
+ $(LINUX_DIR)/lib/crypto/libsha256.ko@ge5.4
|
|
AUTOLOAD:=$(call AutoLoad,09,sha256_generic)
|
|
$(call AddDepends/crypto)
|
|
endef
|
|
@@ -734,6 +766,7 @@ define KernelPackage/crypto-sha512
|
|
DEPENDS:=+kmod-crypto-hash
|
|
KCONFIG:= \
|
|
CONFIG_CRYPTO_SHA512 \
|
|
+ CONFIG_CRYPTO_SHA512_ARM \
|
|
CONFIG_CRYPTO_SHA512_OCTEON \
|
|
CONFIG_CRYPTO_SHA512_SSSE3
|
|
FILES:=$(LINUX_DIR)/crypto/sha512_generic.ko
|
|
@@ -741,11 +774,22 @@ define KernelPackage/crypto-sha512
|
|
$(call AddDepends/crypto)
|
|
endef
|
|
|
|
+define KernelPackage/crypto-sha512/arm
|
|
+ FILES+=$(LINUX_DIR)/arch/arm/crypto/sha512-arm.ko
|
|
+ AUTOLOAD+=$(call AutoLoad,09,sha512-arm)
|
|
+endef
|
|
+
|
|
+KernelPackage/crypto-sha512/imx6=$(KernelPackage/crypto-sha512/arm)
|
|
+KernelPackage/crypto-sha512/ipq40xx=$(KernelPackage/crypto-sha512/arm)
|
|
+KernelPackage/crypto-sha512/mvebu/cortexa9=$(KernelPackage/crypto-sha512/arm)
|
|
+
|
|
define KernelPackage/crypto-sha512/octeon
|
|
FILES+=$(LINUX_DIR)/arch/mips/cavium-octeon/crypto/octeon-sha512.ko
|
|
AUTOLOAD+=$(call AutoLoad,09,octeon-sha512)
|
|
endef
|
|
|
|
+KernelPackage/crypto-sha512/tegra=$(KernelPackage/crypto-sha512/arm)
|
|
+
|
|
define KernelPackage/crypto-sha512/x86/64
|
|
FILES+=$(LINUX_DIR)/arch/x86/crypto/sha512-ssse3.ko
|
|
AUTOLOAD+=$(call AutoLoad,09,sha512-ssse3)
|
|
@@ -768,6 +812,7 @@ define KernelPackage/crypto-user
|
|
TITLE:=CryptoAPI userspace interface
|
|
DEPENDS:=+kmod-crypto-hash +kmod-crypto-manager
|
|
KCONFIG:= \
|
|
+ CONFIG_CRYPTO_USER \
|
|
CONFIG_CRYPTO_USER_API \
|
|
CONFIG_CRYPTO_USER_API_AEAD \
|
|
CONFIG_CRYPTO_USER_API_HASH \
|
|
@@ -778,8 +823,9 @@ define KernelPackage/crypto-user
|
|
$(LINUX_DIR)/crypto/algif_aead.ko \
|
|
$(LINUX_DIR)/crypto/algif_hash.ko \
|
|
$(LINUX_DIR)/crypto/algif_rng.ko \
|
|
- $(LINUX_DIR)/crypto/algif_skcipher.ko
|
|
- AUTOLOAD:=$(call AutoLoad,09,af_alg algif_aead algif_hash algif_rng algif_skcipher)
|
|
+ $(LINUX_DIR)/crypto/algif_skcipher.ko \
|
|
+ $(LINUX_DIR)/crypto/crypto_user.ko
|
|
+ AUTOLOAD:=$(call AutoLoad,09,af_alg algif_aead algif_hash algif_rng algif_skcipher crypto_user)
|
|
$(call AddDepends/crypto)
|
|
endef
|
|
|
|
diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile
|
|
index d26bcb813e..1782bae0f8 100644
|
|
--- a/package/kernel/mac80211/Makefile
|
|
+++ b/package/kernel/mac80211/Makefile
|
|
@@ -1,4 +1,4 @@
|
|
-#
|
|
+#
|
|
# Copyright (C) 2007-2015 OpenWrt.org
|
|
#
|
|
# This is free software, licensed under the GNU General Public License v2.
|
|
diff --git a/package/kernel/mac80211/patches/build/100-backports-pci-Include-linux-pci-aspm.h.patch b/package/kernel/mac80211/patches/build/100-backports-pci-Include-linux-pci-aspm.h.patch
|
|
new file mode 100644
|
|
index 0000000000..5faeb96748
|
|
--- /dev/null
|
|
+++ b/package/kernel/mac80211/patches/build/100-backports-pci-Include-linux-pci-aspm.h.patch
|
|
@@ -0,0 +1,24 @@
|
|
+From: Hauke Mehrtens <hauke@hauke-m.de>
|
|
+Date: Fri, 27 Sep 2019 23:12:08 +0200
|
|
+Subject: [PATCH] backports: pci: Include linux/pci-aspm.h
|
|
+
|
|
+In upstream commit 7ce2e76a0420 linux/pci-aspm.h was removed and the
|
|
+content included into pci.h. Add an include to have the functions
|
|
+defined in linux/pci-aspm.h available when linux/pci.h is included.
|
|
+
|
|
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
|
+---
|
|
+
|
|
+--- a/backport-include/linux/pci.h
|
|
++++ b/backport-include/linux/pci.h
|
|
+@@ -3,6 +3,10 @@
|
|
+ #include_next <linux/pci.h>
|
|
+ #include <linux/version.h>
|
|
+
|
|
++#if LINUX_VERSION_IS_LESS(5,4,0)
|
|
++#include <linux/pci-aspm.h>
|
|
++#endif
|
|
++
|
|
+ #ifndef module_pci_driver
|
|
+ /**
|
|
+ * module_pci_driver() - Helper macro for registering a PCI driver
|
|
diff --git a/package/kernel/mac80211/patches/build/101-backport-add-pci_disable_link_state-wrapper-with-ret.patch b/package/kernel/mac80211/patches/build/101-backport-add-pci_disable_link_state-wrapper-with-ret.patch
|
|
new file mode 100644
|
|
index 0000000000..a41879184b
|
|
--- /dev/null
|
|
+++ b/package/kernel/mac80211/patches/build/101-backport-add-pci_disable_link_state-wrapper-with-ret.patch
|
|
@@ -0,0 +1,43 @@
|
|
+From: Felix Fietkau <nbd@nbd.name>
|
|
+Date: Mon, 28 Oct 2019 15:20:40 +0100
|
|
+Subject: [PATCH] backport: add pci_disable_link_state wrapper with return code
|
|
+
|
|
+The signature of pci_disable_link_state was changed to indicate if the state
|
|
+was successfully disabled. Since the old version did not have this, add a
|
|
+wrapper which checks the pcie register to determine the return code
|
|
+
|
|
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
+---
|
|
+
|
|
+--- a/backport-include/linux/pci.h
|
|
++++ b/backport-include/linux/pci.h
|
|
+@@ -236,4 +236,29 @@ static inline struct pci_dev *pcie_find_
|
|
+ (PCI_IRQ_LEGACY | PCI_IRQ_MSI | PCI_IRQ_MSIX)
|
|
+ #endif
|
|
+
|
|
++#if defined(CONFIG_PCI) && LINUX_VERSION_IS_LESS(5,3,0)
|
|
++
|
|
++static inline int
|
|
++LINUX_BACKPORT(pci_disable_link_state)(struct pci_dev *pdev, int state)
|
|
++{
|
|
++ u16 aspmc;
|
|
++
|
|
++ pci_disable_link_state(pdev, state);
|
|
++
|
|
++ pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &aspmc);
|
|
++ if ((state & PCIE_LINK_STATE_L0S) &&
|
|
++ (aspmc & PCI_EXP_LNKCTL_ASPM_L0S))
|
|
++ return -EPERM;
|
|
++
|
|
++ if ((state & PCIE_LINK_STATE_L1) &&
|
|
++ (aspmc & PCI_EXP_LNKCTL_ASPM_L1))
|
|
++ return -EPERM;
|
|
++
|
|
++ return 0;
|
|
++}
|
|
++
|
|
++#define pci_disable_link_state LINUX_BACKPORT(pci_disable_link_state)
|
|
++
|
|
++#endif
|
|
++
|
|
+ #endif /* _BACKPORT_LINUX_PCI_H */
|
|
diff --git a/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch b/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch
|
|
new file mode 100644
|
|
index 0000000000..c486b2251b
|
|
--- /dev/null
|
|
+++ b/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch
|
|
@@ -0,0 +1,44 @@
|
|
+From: David Bauer <mail@david-bauer.net>
|
|
+Date: Mon, 16 Dec 2019 20:47:06 +0100
|
|
+Subject: [PATCH] rt2x00: add throughput LED trigger
|
|
+
|
|
+This adds a (currently missing) throughput LED trigger for the rt2x00
|
|
+driver. Previously, LED triggers had to be assigned to the netdev, which
|
|
+was limited to a single VAP.
|
|
+
|
|
+Signed-off-by: David Bauer <mail@david-bauer.net>
|
|
+Tested-by: Christoph Krapp <achterin@googlemail.com>
|
|
+
|
|
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
|
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
|
+@@ -1140,6 +1140,19 @@ static void rt2x00lib_remove_hw(struct r
|
|
+ kfree(rt2x00dev->spec.channels_info);
|
|
+ }
|
|
+
|
|
++static const struct ieee80211_tpt_blink rt2x00_tpt_blink[] = {
|
|
++ { .throughput = 0 * 1024, .blink_time = 334 },
|
|
++ { .throughput = 1 * 1024, .blink_time = 260 },
|
|
++ { .throughput = 2 * 1024, .blink_time = 220 },
|
|
++ { .throughput = 5 * 1024, .blink_time = 190 },
|
|
++ { .throughput = 10 * 1024, .blink_time = 170 },
|
|
++ { .throughput = 25 * 1024, .blink_time = 150 },
|
|
++ { .throughput = 54 * 1024, .blink_time = 130 },
|
|
++ { .throughput = 120 * 1024, .blink_time = 110 },
|
|
++ { .throughput = 265 * 1024, .blink_time = 80 },
|
|
++ { .throughput = 586 * 1024, .blink_time = 50 },
|
|
++};
|
|
++
|
|
+ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
|
|
+ {
|
|
+ struct hw_mode_spec *spec = &rt2x00dev->spec;
|
|
+@@ -1222,6 +1235,10 @@ static int rt2x00lib_probe_hw(struct rt2
|
|
+
|
|
+ #undef RT2X00_TASKLET_INIT
|
|
+
|
|
++ ieee80211_create_tpt_led_trigger(rt2x00dev->hw,
|
|
++ IEEE80211_TPT_LEDTRIG_FL_RADIO, rt2x00_tpt_blink,
|
|
++ ARRAY_SIZE(rt2x00_tpt_blink));
|
|
++
|
|
+ /*
|
|
+ * Register HW.
|
|
+ */
|
|
diff --git a/package/kernel/mac80211/patches/subsys/368-cfg80211-add-local-BSS-receive-time-to-survey-inform.patch b/package/kernel/mac80211/patches/subsys/368-cfg80211-add-local-BSS-receive-time-to-survey-inform.patch
|
|
new file mode 100644
|
|
index 0000000000..e6d384784e
|
|
--- /dev/null
|
|
+++ b/package/kernel/mac80211/patches/subsys/368-cfg80211-add-local-BSS-receive-time-to-survey-inform.patch
|
|
@@ -0,0 +1,77 @@
|
|
+From: Felix Fietkau <nbd@nbd.name>
|
|
+Date: Wed, 28 Aug 2019 12:13:55 +0200
|
|
+Subject: [PATCH] cfg80211: add local BSS receive time to survey information
|
|
+
|
|
+This is useful for checking how much airtime is being used up by other
|
|
+transmissions on the channel, e.g. by calculating (time_rx - time_bss_rx)
|
|
+or (time_busy - time_bss_rx - time_tx)
|
|
+
|
|
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
+---
|
|
+
|
|
+--- a/include/net/cfg80211.h
|
|
++++ b/include/net/cfg80211.h
|
|
+@@ -668,6 +668,7 @@ ieee80211_chandef_max_power(struct cfg80
|
|
+ * @SURVEY_INFO_TIME_RX: receive time was filled in
|
|
+ * @SURVEY_INFO_TIME_TX: transmit time was filled in
|
|
+ * @SURVEY_INFO_TIME_SCAN: scan time was filled in
|
|
++ * @SURVEY_INFO_TIME_BSS_RX: local BSS receive time was filled in
|
|
+ *
|
|
+ * Used by the driver to indicate which info in &struct survey_info
|
|
+ * it has filled in during the get_survey().
|
|
+@@ -681,6 +682,7 @@ enum survey_info_flags {
|
|
+ SURVEY_INFO_TIME_RX = BIT(5),
|
|
+ SURVEY_INFO_TIME_TX = BIT(6),
|
|
+ SURVEY_INFO_TIME_SCAN = BIT(7),
|
|
++ SURVEY_INFO_TIME_BSS_RX = BIT(8),
|
|
+ };
|
|
+
|
|
+ /**
|
|
+@@ -697,6 +699,7 @@ enum survey_info_flags {
|
|
+ * @time_rx: amount of time the radio spent receiving data
|
|
+ * @time_tx: amount of time the radio spent transmitting data
|
|
+ * @time_scan: amount of time the radio spent for scanning
|
|
++ * @time_bss_rx: amount of time the radio spent receiving data on a local BSS
|
|
+ *
|
|
+ * Used by dump_survey() to report back per-channel survey information.
|
|
+ *
|
|
+@@ -711,6 +714,7 @@ struct survey_info {
|
|
+ u64 time_rx;
|
|
+ u64 time_tx;
|
|
+ u64 time_scan;
|
|
++ u64 time_bss_rx;
|
|
+ u32 filled;
|
|
+ s8 noise;
|
|
+ };
|
|
+--- a/include/uapi/linux/nl80211.h
|
|
++++ b/include/uapi/linux/nl80211.h
|
|
+@@ -3693,6 +3693,8 @@ enum nl80211_user_reg_hint_type {
|
|
+ * @NL80211_SURVEY_INFO_TIME_SCAN: time the radio spent for scan
|
|
+ * (on this channel or globally)
|
|
+ * @NL80211_SURVEY_INFO_PAD: attribute used for padding for 64-bit alignment
|
|
++ * @NL80211_SURVEY_INFO_TIME_BSS_RX: amount of time the radio spent
|
|
++ * receiving local BSS data
|
|
+ * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number
|
|
+ * currently defined
|
|
+ * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use
|
|
+@@ -3709,6 +3711,7 @@ enum nl80211_survey_info {
|
|
+ NL80211_SURVEY_INFO_TIME_TX,
|
|
+ NL80211_SURVEY_INFO_TIME_SCAN,
|
|
+ NL80211_SURVEY_INFO_PAD,
|
|
++ NL80211_SURVEY_INFO_TIME_BSS_RX,
|
|
+
|
|
+ /* keep last */
|
|
+ __NL80211_SURVEY_INFO_AFTER_LAST,
|
|
+--- a/net/wireless/nl80211.c
|
|
++++ b/net/wireless/nl80211.c
|
|
+@@ -8367,6 +8367,10 @@ static int nl80211_send_survey(struct sk
|
|
+ nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_SCAN,
|
|
+ survey->time_scan, NL80211_SURVEY_INFO_PAD))
|
|
+ goto nla_put_failure;
|
|
++ if ((survey->filled & SURVEY_INFO_TIME_BSS_RX) &&
|
|
++ nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BSS_RX,
|
|
++ survey->time_bss_rx, NL80211_SURVEY_INFO_PAD))
|
|
++ goto nla_put_failure;
|
|
+
|
|
+ nla_nest_end(msg, infoattr);
|
|
+
|
|
diff --git a/package/kernel/mac80211/patches/subsys/522-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/subsys/522-mac80211_configure_antenna_gain.patch
|
|
index 81007b87cc..cf4fdc13e9 100644
|
|
--- a/package/kernel/mac80211/patches/subsys/522-mac80211_configure_antenna_gain.patch
|
|
+++ b/package/kernel/mac80211/patches/subsys/522-mac80211_configure_antenna_gain.patch
|
|
@@ -1,6 +1,6 @@
|
|
--- a/include/net/cfg80211.h
|
|
+++ b/include/net/cfg80211.h
|
|
-@@ -2968,6 +2968,7 @@ struct cfg80211_external_auth_params {
|
|
+@@ -2972,6 +2972,7 @@ struct cfg80211_external_auth_params {
|
|
* (as advertised by the nl80211 feature flag.)
|
|
* @get_tx_power: store the current TX power into the dbm variable;
|
|
* return 0 if successful
|
|
@@ -8,7 +8,7 @@
|
|
*
|
|
* @set_wds_peer: set the WDS peer for a WDS interface
|
|
*
|
|
-@@ -3268,6 +3269,7 @@ struct cfg80211_ops {
|
|
+@@ -3272,6 +3273,7 @@ struct cfg80211_ops {
|
|
enum nl80211_tx_power_setting type, int mbm);
|
|
int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|
int *dbm);
|
|
diff --git a/package/kernel/mt76/Makefile b/package/kernel/mt76/Makefile
|
|
index db0bf04d0a..921c32c56b 100644
|
|
--- a/package/kernel/mt76/Makefile
|
|
+++ b/package/kernel/mt76/Makefile
|
|
@@ -8,9 +8,9 @@ PKG_LICENSE_FILES:=
|
|
|
|
PKG_SOURCE_URL:=https://github.com/openwrt/mt76
|
|
PKG_SOURCE_PROTO:=git
|
|
-PKG_SOURCE_DATE:=2019-08-22
|
|
-PKG_SOURCE_VERSION:=2a0edbb4473b71dfaa4756f7189abf6cb7f7be8b
|
|
-PKG_MIRROR_HASH:=a37975c179b929716c40d19fdcd5b131386d7f497eb8cd5d848be74e76d50d21
|
|
+PKG_SOURCE_DATE:=2020-03-10
|
|
+PKG_SOURCE_VERSION:=08054d5ab1350fcb8563feb90e6ab7f8f4a0a1b7
|
|
+PKG_MIRROR_HASH:=b41a3cab1485c68befb1dcb4c1e426d41705db1b2a57851dafd6e8f75eeea3d7
|
|
|
|
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
|
PKG_BUILD_PARALLEL:=1
|
|
@@ -246,12 +246,12 @@ define KernelPackage/mt7603/install
|
|
endef
|
|
|
|
define KernelPackage/mt7615e/install
|
|
- $(INSTALL_DIR) $(1)/lib/firmware
|
|
+ $(INSTALL_DIR) $(1)/lib/firmware/mediatek
|
|
cp \
|
|
$(PKG_BUILD_DIR)/firmware/mt7615_cr4.bin \
|
|
$(PKG_BUILD_DIR)/firmware/mt7615_n9.bin \
|
|
$(PKG_BUILD_DIR)/firmware/mt7615_rom_patch.bin \
|
|
- $(1)/lib/firmware
|
|
+ $(1)/lib/firmware/mediatek
|
|
endef
|
|
|
|
$(eval $(call KernelPackage,mt76-core))
|
|
@@ -266,4 +266,4 @@ $(eval $(call KernelPackage,mt76x2u))
|
|
$(eval $(call KernelPackage,mt76x2))
|
|
$(eval $(call KernelPackage,mt7603))
|
|
$(eval $(call KernelPackage,mt7615e))
|
|
-$(eval $(call KernelPackage,mt76))
|
|
+$(eval $(call KernelPackage,mt76))
|
|
\ No newline at end of file
|
|
diff --git a/package/lean/luci-app-adbyby-plus/po/zh-cn/adbyby.po b/package/lean/luci-app-adbyby-plus/po/zh-cn/adbyby.po
|
|
index 86a01d9b55..b462b053e7 100644
|
|
--- a/package/lean/luci-app-adbyby-plus/po/zh-cn/adbyby.po
|
|
+++ b/package/lean/luci-app-adbyby-plus/po/zh-cn/adbyby.po
|
|
@@ -91,6 +91,9 @@ msgstr "更新失败!"
|
|
msgid "No new data!"
|
|
msgstr "你已经是最新数据,无需更新!"
|
|
|
|
+msgid "Total Records:"
|
|
+msgstr "新的总纪录数:"
|
|
+
|
|
msgid "Delete All Subscribe Rules"
|
|
msgstr "清空所有订阅的规则库"
|
|
|
|
diff --git a/package/lean/luci-app-autoreboot/root/etc/init.d/autoreboot b/package/lean/luci-app-autoreboot/root/etc/init.d/autoreboot
|
|
index 934477d415..aba2fce12a 100755
|
|
--- a/package/lean/luci-app-autoreboot/root/etc/init.d/autoreboot
|
|
+++ b/package/lean/luci-app-autoreboot/root/etc/init.d/autoreboot
|
|
@@ -19,10 +19,12 @@ run_reboot()
|
|
week="*"
|
|
fi
|
|
sed -i '/reboot/d' /etc/crontabs/root >/dev/null 2>&1
|
|
+ /etc/init.d/cron restart
|
|
echo "$minute $hour * * $week sleep 5 && touch /etc/banner && reboot" >> /etc/crontabs/root
|
|
echo "Auto REBOOT has started."
|
|
else
|
|
sed -i '/reboot/d' /etc/crontabs/root >/dev/null 2>&1
|
|
+ /etc/init.d/cron restart
|
|
echo "Auto REBOOT has started."
|
|
fi
|
|
}
|
|
diff --git a/package/lean/luci-app-nps/po/zh-cn/nps.po b/package/lean/luci-app-nps/po/zh-cn/nps.po
|
|
index 4fb9ad411e..3891bc0c89 100644
|
|
--- a/package/lean/luci-app-nps/po/zh-cn/nps.po
|
|
+++ b/package/lean/luci-app-nps/po/zh-cn/nps.po
|
|
@@ -26,4 +26,19 @@ msgid "<b style='color:green;'>Nps is running.</b>"
|
|
msgstr "<b style='color:green;'>Nps 运行中</b>"
|
|
|
|
msgid "<b style='color:red;'>Nps is not running.</b>"
|
|
-msgstr "<b style='color:red;'>Nps 未运行</b>"
|
|
\ No newline at end of file
|
|
+msgstr "<b style='color:red;'>Nps 未运行</b>"
|
|
+
|
|
+msgid "Basic Setting"
|
|
+msgstr "基本设置"
|
|
+
|
|
+msgid "Protocol Type"
|
|
+msgstr "协议类型"
|
|
+
|
|
+msgid "Server"
|
|
+msgstr "服务端地址"
|
|
+
|
|
+msgid "TCP Protocol"
|
|
+msgstr "TCP"
|
|
+
|
|
+msgid "KCP Protocol"
|
|
+msgstr "KCP"
|
|
diff --git a/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm
|
|
index 67aad5f534..778de53bf2 100644
|
|
--- a/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm
|
|
+++ b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm
|
|
@@ -221,7 +221,7 @@
|
|
var others = serverPart[1].split('?');
|
|
var port = others[0]
|
|
var queryParam = {}
|
|
- if(others.length > 0) {
|
|
+ if(others.length > 1) {
|
|
var queryParams = others[1]
|
|
var queryArray = queryParams.split('&')
|
|
for (i = 0; i < queryArray.length; i++) {
|
|
diff --git a/package/lean/npc/Makefile b/package/lean/npc/Makefile
|
|
index e3b3527868..bb97ff1f91 100644
|
|
--- a/package/lean/npc/Makefile
|
|
+++ b/package/lean/npc/Makefile
|
|
@@ -7,7 +7,7 @@
|
|
include $(TOPDIR)/rules.mk
|
|
|
|
PKG_NAME:=npc
|
|
-PKG_VERSION:=0.26.4
|
|
+PKG_VERSION:=0.26.5
|
|
PKG_RELEASE:=2
|
|
|
|
ifeq ($(ARCH),mipsel)
|
|
diff --git a/package/libs/openssl/Config.in b/package/libs/openssl/Config.in
|
|
index 42d3845081..ecfd2834b6 100644
|
|
--- a/package/libs/openssl/Config.in
|
|
+++ b/package/libs/openssl/Config.in
|
|
@@ -38,7 +38,7 @@ config OPENSSL_WITH_ASM
|
|
|
|
config OPENSSL_WITH_SSE2
|
|
bool
|
|
- default y if !TARGET_x86_legacy && !TARGET_x86_geode
|
|
+ default y if x86_64 || i386 && !TARGET_x86_legacy
|
|
prompt "Enable use of x86 SSE2 instructions"
|
|
depends on OPENSSL_WITH_ASM && x86_64 || i386
|
|
help
|
|
@@ -248,6 +248,7 @@ config OPENSSL_ENGINE
|
|
|
|
config OPENSSL_ENGINE_BUILTIN
|
|
bool "Build chosen engines into libcrypto"
|
|
+ default y
|
|
depends on OPENSSL_ENGINE
|
|
help
|
|
This builds all chosen engines into libcrypto.so, instead of building
|
|
@@ -257,6 +258,7 @@ config OPENSSL_ENGINE_BUILTIN
|
|
|
|
config OPENSSL_ENGINE_BUILTIN_AFALG
|
|
bool
|
|
+ default y
|
|
prompt "Acceleration support through AF_ALG sockets engine"
|
|
depends on OPENSSL_ENGINE_BUILTIN && KERNEL_AIO
|
|
select PACKAGE_libopenssl-conf
|
|
diff --git a/package/libs/openssl/Makefile b/package/libs/openssl/Makefile
|
|
index 627f2bf62f..5c154a9054 100644
|
|
--- a/package/libs/openssl/Makefile
|
|
+++ b/package/libs/openssl/Makefile
|
|
@@ -11,7 +11,7 @@ PKG_NAME:=openssl
|
|
PKG_BASE:=1.1.1
|
|
PKG_BUGFIX:=e-dev
|
|
PKG_VERSION:=$(PKG_BASE)$(PKG_BUGFIX)
|
|
-PKG_RELEASE:=1
|
|
+PKG_RELEASE:=2
|
|
|
|
PKG_SOURCE_PROTO:=git
|
|
PKG_SOURCE_URL:=https://github.com/openssl/openssl.git
|
|
diff --git a/target/linux/generic/backport-4.14/600-ipv6-addrconf-call-ipv6_mc_up-for-non-Ethernet-inter.patch b/target/linux/generic/backport-4.14/600-ipv6-addrconf-call-ipv6_mc_up-for-non-Ethernet-inter.patch
|
|
new file mode 100644
|
|
index 0000000000..ba0d137096
|
|
--- /dev/null
|
|
+++ b/target/linux/generic/backport-4.14/600-ipv6-addrconf-call-ipv6_mc_up-for-non-Ethernet-inter.patch
|
|
@@ -0,0 +1,71 @@
|
|
+From 82afdcd4ec3c8ca6551cbf7c43c09e2fd240487a Mon Sep 17 00:00:00 2001
|
|
+From: Hangbin Liu <liuhangbin@gmail.com>
|
|
+Date: Tue, 10 Mar 2020 15:27:37 +0800
|
|
+Subject: [PATCH] ipv6/addrconf: call ipv6_mc_up() for non-Ethernet interface
|
|
+MIME-Version: 1.0
|
|
+Content-Type: text/plain; charset=UTF-8
|
|
+Content-Transfer-Encoding: 8bit
|
|
+
|
|
+Rafał found an issue that for non-Ethernet interface, if we down and up
|
|
+frequently, the memory will be consumed slowly.
|
|
+
|
|
+The reason is we add allnodes/allrouters addressed in multicast list in
|
|
+ipv6_add_dev(). When link down, we call ipv6_mc_down(), store all multicast
|
|
+addresses via mld_add_delrec(). But when link up, we don't call ipv6_mc_up()
|
|
+for non-Ethernet interface to remove the addresses. This makes idev->mc_tomb
|
|
+getting bigger and bigger. The call stack looks like:
|
|
+
|
|
+addrconf_notify(NETDEV_REGISTER)
|
|
+ ipv6_add_dev
|
|
+ ipv6_dev_mc_inc(ff01::1)
|
|
+ ipv6_dev_mc_inc(ff02::1)
|
|
+ ipv6_dev_mc_inc(ff02::2)
|
|
+
|
|
+addrconf_notify(NETDEV_UP)
|
|
+ addrconf_dev_config
|
|
+ /* Alas, we support only Ethernet autoconfiguration. */
|
|
+ return;
|
|
+
|
|
+addrconf_notify(NETDEV_DOWN)
|
|
+ addrconf_ifdown
|
|
+ ipv6_mc_down
|
|
+ igmp6_group_dropped(ff02::2)
|
|
+ mld_add_delrec(ff02::2)
|
|
+ igmp6_group_dropped(ff02::1)
|
|
+ igmp6_group_dropped(ff01::1)
|
|
+
|
|
+After investigating, I can't found a rule to disable multicast on
|
|
+non-Ethernet interface. In RFC2460, the link could be Ethernet, PPP, ATM,
|
|
+tunnels, etc. In IPv4, it doesn't check the dev type when calls ip_mc_up()
|
|
+in inetdev_event(). Even for IPv6, we don't check the dev type and call
|
|
+ipv6_add_dev(), ipv6_dev_mc_inc() after register device.
|
|
+
|
|
+So I think it's OK to fix this memory consumer by calling ipv6_mc_up() for
|
|
+non-Ethernet interface.
|
|
+
|
|
+v2: Also check IFF_MULTICAST flag to make sure the interface supports
|
|
+ multicast
|
|
+
|
|
+Reported-by: Rafał Miłecki <zajec5@gmail.com>
|
|
+Tested-by: Rafał Miłecki <zajec5@gmail.com>
|
|
+Fixes: 74235a25c673 ("[IPV6] addrconf: Fix IPv6 on tuntap tunnels")
|
|
+Fixes: 1666d49e1d41 ("mld: do not remove mld souce list info when set link down")
|
|
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
+Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
+---
|
|
+ net/ipv6/addrconf.c | 4 ++++
|
|
+ 1 file changed, 4 insertions(+)
|
|
+
|
|
+--- a/net/ipv6/addrconf.c
|
|
++++ b/net/ipv6/addrconf.c
|
|
+@@ -3223,6 +3223,10 @@ static void addrconf_dev_config(struct n
|
|
+ (dev->type != ARPHRD_TUNNEL) &&
|
|
+ (dev->type != ARPHRD_NONE)) {
|
|
+ /* Alas, we support only Ethernet autoconfiguration. */
|
|
++ idev = __in6_dev_get(dev);
|
|
++ if (!IS_ERR_OR_NULL(idev) && dev->flags & IFF_UP &&
|
|
++ dev->flags & IFF_MULTICAST)
|
|
++ ipv6_mc_up(idev);
|
|
+ return;
|
|
+ }
|
|
+
|
|
diff --git a/target/linux/generic/backport-4.19/410-mtd-fix-calculating-partition-end-address.patch b/target/linux/generic/backport-4.19/410-mtd-fix-calculating-partition-end-address.patch
|
|
new file mode 100644
|
|
index 0000000000..4027bfd714
|
|
--- /dev/null
|
|
+++ b/target/linux/generic/backport-4.19/410-mtd-fix-calculating-partition-end-address.patch
|
|
@@ -0,0 +1,28 @@
|
|
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
|
+Date: Mon, 9 Mar 2020 08:30:19 +0100
|
|
+Subject: [PATCH] mtd: fix calculating partition end address
|
|
+MIME-Version: 1.0
|
|
+Content-Type: text/plain; charset=UTF-8
|
|
+Content-Transfer-Encoding: 8bit
|
|
+
|
|
+This fixes check for partitions that don't start at beginning of their
|
|
+parents. Missing partition's offset in formula could result in forcing
|
|
+read-only incorrectly.
|
|
+
|
|
+Fixes: 6750f61a13a0 ("mtd: improve calculating partition boundaries when checking for alignment")
|
|
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
|
+---
|
|
+ drivers/mtd/mtdpart.c | 2 +-
|
|
+ 1 file changed, 1 insertion(+), 1 deletion(-)
|
|
+
|
|
+--- a/drivers/mtd/mtdpart.c
|
|
++++ b/drivers/mtd/mtdpart.c
|
|
+@@ -538,7 +538,7 @@ static struct mtd_part *allocate_partiti
|
|
+ part->name);
|
|
+ }
|
|
+
|
|
+- tmp = part_absolute_offset(parent) + slave->mtd.size;
|
|
++ tmp = part_absolute_offset(parent) + slave->offset + slave->mtd.size;
|
|
+ remainder = do_div(tmp, wr_alignment);
|
|
+ if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) {
|
|
+ slave->mtd.flags &= ~MTD_WRITEABLE;
|
|
diff --git a/target/linux/generic/backport-4.19/464-v5.6-mtd-spi-nor-Add-4B_OPCODES-flag-to-w25q256.patch b/target/linux/generic/backport-4.19/464-v5.6-mtd-spi-nor-Add-4B_OPCODES-flag-to-w25q256.patch
|
|
new file mode 100644
|
|
index 0000000000..db9f379c81
|
|
--- /dev/null
|
|
+++ b/target/linux/generic/backport-4.19/464-v5.6-mtd-spi-nor-Add-4B_OPCODES-flag-to-w25q256.patch
|
|
@@ -0,0 +1,27 @@
|
|
+From 10050a02f7d508fa88f70fcfceefbacd13488ca7 Mon Sep 17 00:00:00 2001
|
|
+From: Robert Marko <robimarko@gmail.com>
|
|
+Date: Mon, 23 Dec 2019 17:05:49 +0200
|
|
+Subject: [PATCH] mtd: spi-nor: Add 4B_OPCODES flag to w25q256
|
|
+
|
|
+The w25q256 supports 4-byte opcodes so lets add the flag.
|
|
+Tested on OpenWrt under 4.19.82 kernel on 8devices Habanero.
|
|
+
|
|
+Signed-off-by: Robert Marko <robimarko@gmail.com>
|
|
+Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
|
|
+---
|
|
+ drivers/mtd/spi-nor/spi-nor.c | 4 +++-
|
|
+ 1 file changed, 3 insertions(+), 1 deletion(-)
|
|
+
|
|
+--- a/drivers/mtd/spi-nor/spi-nor.c
|
|
++++ b/drivers/mtd/spi-nor/spi-nor.c
|
|
+@@ -1244,7 +1244,9 @@ static const struct flash_info spi_nor_i
|
|
+ { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) },
|
|
+ { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) },
|
|
+ { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
|
|
+- { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
|
++ { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512,
|
|
++ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
|
|
++ SPI_NOR_4B_OPCODES) },
|
|
+ { "w25m512jv", INFO(0xef7119, 0, 64 * 1024, 1024,
|
|
+ SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ) },
|
|
+
|
|
diff --git a/target/linux/generic/backport-4.19/499-v4.22-iio-add-IIO_MASSCONCENTRATION-channel-type.patch b/target/linux/generic/backport-4.19/499-v4.22-iio-add-IIO_MASSCONCENTRATION-channel-type.patch
|
|
new file mode 100644
|
|
index 0000000000..bceb735146
|
|
--- /dev/null
|
|
+++ b/target/linux/generic/backport-4.19/499-v4.22-iio-add-IIO_MASSCONCENTRATION-channel-type.patch
|
|
@@ -0,0 +1,136 @@
|
|
+From 17abc9ec68b73ddeb262a507a62421016b9c54d5 Mon Sep 17 00:00:00 2001
|
|
+From: Tomasz Duszynski <tduszyns@gmail.com>
|
|
+Date: Fri, 14 Dec 2018 19:28:01 +0100
|
|
+Subject: [PATCH] iio: add IIO_MASSCONCENTRATION channel type
|
|
+
|
|
+Measuring particulate matter in ug / m3 (micro-grams per cubic meter)
|
|
+is de facto standard. Existing air quality sensors usually follow
|
|
+this convention and are capable of returning measurements using
|
|
+this unit.
|
|
+
|
|
+IIO currently does not offer suitable channel type for this
|
|
+type of measurements hence this patch adds this.
|
|
+
|
|
+In addition, extra modifiers are introduced used for distinguishing
|
|
+between fine pm1, pm2p5 and coarse pm4, pm10 particle measurements, i.e
|
|
+IIO_MOD_PM1, IIO_MOD_PM25 and IIO_MOD_PM4, IIO_MOD_PM10.
|
|
+
|
|
+pmX consists of particles with aerodynamic diameter less or equal to
|
|
+X micrometers.
|
|
+
|
|
+Signed-off-by: Tomasz Duszynski <tduszyns@gmail.com>
|
|
+Acked-by: Matt Ranostay <matt.ranostay@konsulko.com>
|
|
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
+---
|
|
+ Documentation/ABI/testing/sysfs-bus-iio | 17 ++++++++++++++++-
|
|
+ drivers/iio/industrialio-core.c | 5 +++++
|
|
+ include/uapi/linux/iio/types.h | 5 +++++
|
|
+ tools/iio/iio_event_monitor.c | 10 ++++++++++
|
|
+ 4 files changed, 36 insertions(+), 1 deletion(-)
|
|
+
|
|
+--- a/Documentation/ABI/testing/sysfs-bus-iio
|
|
++++ b/Documentation/ABI/testing/sysfs-bus-iio
|
|
+@@ -1684,4 +1684,19 @@ KernelVersion: 4.18
|
|
+ Contact: linux-iio@vger.kernel.org
|
|
+ Description:
|
|
+ Raw (unscaled) phase difference reading from channel Y
|
|
+- that can be processed to radians.
|
|
+\ No newline at end of file
|
|
++ that can be processed to radians.
|
|
++
|
|
++What: /sys/bus/iio/devices/iio:deviceX/in_massconcentration_pm1_input
|
|
++What: /sys/bus/iio/devices/iio:deviceX/in_massconcentrationY_pm1_input
|
|
++What: /sys/bus/iio/devices/iio:deviceX/in_massconcentration_pm2p5_input
|
|
++What: /sys/bus/iio/devices/iio:deviceX/in_massconcentrationY_pm2p5_input
|
|
++What: /sys/bus/iio/devices/iio:deviceX/in_massconcentration_pm4_input
|
|
++What: /sys/bus/iio/devices/iio:deviceX/in_massconcentrationY_pm4_input
|
|
++What: /sys/bus/iio/devices/iio:deviceX/in_massconcentration_pm10_input
|
|
++What: /sys/bus/iio/devices/iio:deviceX/in_massconcentrationY_pm10_input
|
|
++KernelVersion: 4.22
|
|
++Contact: linux-iio@vger.kernel.org
|
|
++Description:
|
|
++ Mass concentration reading of particulate matter in ug / m3.
|
|
++ pmX consists of particles with aerodynamic diameter less or
|
|
++ equal to X micrometers.
|
|
+--- a/drivers/iio/industrialio-core.c
|
|
++++ b/drivers/iio/industrialio-core.c
|
|
+@@ -87,6 +87,7 @@ static const char * const iio_chan_type_
|
|
+ [IIO_GRAVITY] = "gravity",
|
|
+ [IIO_POSITIONRELATIVE] = "positionrelative",
|
|
+ [IIO_PHASE] = "phase",
|
|
++ [IIO_MASSCONCENTRATION] = "massconcentration",
|
|
+ };
|
|
+
|
|
+ static const char * const iio_modifier_names[] = {
|
|
+@@ -127,6 +128,10 @@ static const char * const iio_modifier_n
|
|
+ [IIO_MOD_Q] = "q",
|
|
+ [IIO_MOD_CO2] = "co2",
|
|
+ [IIO_MOD_VOC] = "voc",
|
|
++ [IIO_MOD_PM1] = "pm1",
|
|
++ [IIO_MOD_PM2P5] = "pm2p5",
|
|
++ [IIO_MOD_PM4] = "pm4",
|
|
++ [IIO_MOD_PM10] = "pm10",
|
|
+ };
|
|
+
|
|
+ /* relies on pairs of these shared then separate */
|
|
+--- a/include/uapi/linux/iio/types.h
|
|
++++ b/include/uapi/linux/iio/types.h
|
|
+@@ -46,6 +46,7 @@ enum iio_chan_type {
|
|
+ IIO_GRAVITY,
|
|
+ IIO_POSITIONRELATIVE,
|
|
+ IIO_PHASE,
|
|
++ IIO_MASSCONCENTRATION,
|
|
+ };
|
|
+
|
|
+ enum iio_modifier {
|
|
+@@ -87,6 +88,10 @@ enum iio_modifier {
|
|
+ IIO_MOD_VOC,
|
|
+ IIO_MOD_LIGHT_UV,
|
|
+ IIO_MOD_LIGHT_DUV,
|
|
++ IIO_MOD_PM1,
|
|
++ IIO_MOD_PM2P5,
|
|
++ IIO_MOD_PM4,
|
|
++ IIO_MOD_PM10,
|
|
+ };
|
|
+
|
|
+ enum iio_event_type {
|
|
+--- a/tools/iio/iio_event_monitor.c
|
|
++++ b/tools/iio/iio_event_monitor.c
|
|
+@@ -60,6 +60,7 @@ static const char * const iio_chan_type_
|
|
+ [IIO_GRAVITY] = "gravity",
|
|
+ [IIO_POSITIONRELATIVE] = "positionrelative",
|
|
+ [IIO_PHASE] = "phase",
|
|
++ [IIO_MASSCONCENTRATION] = "massconcentration",
|
|
+ };
|
|
+
|
|
+ static const char * const iio_ev_type_text[] = {
|
|
+@@ -115,6 +116,10 @@ static const char * const iio_modifier_n
|
|
+ [IIO_MOD_Q] = "q",
|
|
+ [IIO_MOD_CO2] = "co2",
|
|
+ [IIO_MOD_VOC] = "voc",
|
|
++ [IIO_MOD_PM1] = "pm1",
|
|
++ [IIO_MOD_PM2P5] = "pm2p5",
|
|
++ [IIO_MOD_PM4] = "pm4",
|
|
++ [IIO_MOD_PM10] = "pm10",
|
|
+ };
|
|
+
|
|
+ static bool event_is_known(struct iio_event_data *event)
|
|
+@@ -156,6 +161,7 @@ static bool event_is_known(struct iio_ev
|
|
+ case IIO_GRAVITY:
|
|
+ case IIO_POSITIONRELATIVE:
|
|
+ case IIO_PHASE:
|
|
++ case IIO_MASSCONCENTRATION:
|
|
+ break;
|
|
+ default:
|
|
+ return false;
|
|
+@@ -200,6 +206,10 @@ static bool event_is_known(struct iio_ev
|
|
+ case IIO_MOD_Q:
|
|
+ case IIO_MOD_CO2:
|
|
+ case IIO_MOD_VOC:
|
|
++ case IIO_MOD_PM1:
|
|
++ case IIO_MOD_PM2P5:
|
|
++ case IIO_MOD_PM4:
|
|
++ case IIO_MOD_PM10:
|
|
+ break;
|
|
+ default:
|
|
+ return false;
|
|
diff --git a/target/linux/generic/backport-4.19/500-v5.1-iio-chemical-add-support-for-Sensirion-SPS30-sensor.patch b/target/linux/generic/backport-4.19/500-v5.1-iio-chemical-add-support-for-Sensirion-SPS30-sensor.patch
|
|
new file mode 100644
|
|
index 0000000000..d30c7c3cc1
|
|
--- /dev/null
|
|
+++ b/target/linux/generic/backport-4.19/500-v5.1-iio-chemical-add-support-for-Sensirion-SPS30-sensor.patch
|
|
@@ -0,0 +1,454 @@
|
|
+From 232e0f6ddeaee104d64675fe7d0cc142cf955f35 Mon Sep 17 00:00:00 2001
|
|
+From: Tomasz Duszynski <tduszyns@gmail.com>
|
|
+Date: Fri, 14 Dec 2018 19:28:02 +0100
|
|
+Subject: [PATCH] iio: chemical: add support for Sensirion SPS30 sensor
|
|
+
|
|
+Add support for Sensirion SPS30 particulate matter sensor.
|
|
+
|
|
+Signed-off-by: Tomasz Duszynski <tduszyns@gmail.com>
|
|
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
+---
|
|
+ drivers/iio/chemical/Kconfig | 11 +
|
|
+ drivers/iio/chemical/Makefile | 1 +
|
|
+ drivers/iio/chemical/sps30.c | 407 ++++++++++++++++++++++++++++++++++
|
|
+ 3 files changed, 419 insertions(+)
|
|
+ create mode 100644 drivers/iio/chemical/sps30.c
|
|
+
|
|
+--- a/drivers/iio/chemical/Kconfig
|
|
++++ b/drivers/iio/chemical/Kconfig
|
|
+@@ -61,6 +61,17 @@ config IAQCORE
|
|
+ iAQ-Core Continuous/Pulsed VOC (Volatile Organic Compounds)
|
|
+ sensors
|
|
+
|
|
++config SPS30
|
|
++ tristate "SPS30 particulate matter sensor"
|
|
++ depends on I2C
|
|
++ select CRC8
|
|
++ help
|
|
++ Say Y here to build support for the Sensirion SPS30 particulate
|
|
++ matter sensor.
|
|
++
|
|
++ To compile this driver as a module, choose M here: the module will
|
|
++ be called sps30.
|
|
++
|
|
+ config VZ89X
|
|
+ tristate "SGX Sensortech MiCS VZ89X VOC sensor"
|
|
+ depends on I2C
|
|
+--- a/drivers/iio/chemical/Makefile
|
|
++++ b/drivers/iio/chemical/Makefile
|
|
+@@ -9,4 +9,5 @@ obj-$(CONFIG_BME680_I2C) += bme680_i2c.o
|
|
+ obj-$(CONFIG_BME680_SPI) += bme680_spi.o
|
|
+ obj-$(CONFIG_CCS811) += ccs811.o
|
|
+ obj-$(CONFIG_IAQCORE) += ams-iaq-core.o
|
|
++obj-$(CONFIG_SPS30) += sps30.o
|
|
+ obj-$(CONFIG_VZ89X) += vz89x.o
|
|
+--- /dev/null
|
|
++++ b/drivers/iio/chemical/sps30.c
|
|
+@@ -0,0 +1,407 @@
|
|
++// SPDX-License-Identifier: GPL-2.0
|
|
++/*
|
|
++ * Sensirion SPS30 particulate matter sensor driver
|
|
++ *
|
|
++ * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
|
|
++ *
|
|
++ * I2C slave address: 0x69
|
|
++ *
|
|
++ * TODO:
|
|
++ * - support for turning on fan cleaning
|
|
++ * - support for reading/setting auto cleaning interval
|
|
++ */
|
|
++
|
|
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
++
|
|
++#include <asm/unaligned.h>
|
|
++#include <linux/crc8.h>
|
|
++#include <linux/delay.h>
|
|
++#include <linux/i2c.h>
|
|
++#include <linux/iio/buffer.h>
|
|
++#include <linux/iio/iio.h>
|
|
++#include <linux/iio/sysfs.h>
|
|
++#include <linux/iio/trigger_consumer.h>
|
|
++#include <linux/iio/triggered_buffer.h>
|
|
++#include <linux/module.h>
|
|
++
|
|
++#define SPS30_CRC8_POLYNOMIAL 0x31
|
|
++/* max number of bytes needed to store PM measurements or serial string */
|
|
++#define SPS30_MAX_READ_SIZE 48
|
|
++/* sensor measures reliably up to 3000 ug / m3 */
|
|
++#define SPS30_MAX_PM 3000
|
|
++
|
|
++/* SPS30 commands */
|
|
++#define SPS30_START_MEAS 0x0010
|
|
++#define SPS30_STOP_MEAS 0x0104
|
|
++#define SPS30_RESET 0xd304
|
|
++#define SPS30_READ_DATA_READY_FLAG 0x0202
|
|
++#define SPS30_READ_DATA 0x0300
|
|
++#define SPS30_READ_SERIAL 0xd033
|
|
++
|
|
++enum {
|
|
++ PM1,
|
|
++ PM2P5,
|
|
++ PM4,
|
|
++ PM10,
|
|
++};
|
|
++
|
|
++struct sps30_state {
|
|
++ struct i2c_client *client;
|
|
++ /*
|
|
++ * Guards against concurrent access to sensor registers.
|
|
++ * Must be held whenever sequence of commands is to be executed.
|
|
++ */
|
|
++ struct mutex lock;
|
|
++};
|
|
++
|
|
++DECLARE_CRC8_TABLE(sps30_crc8_table);
|
|
++
|
|
++static int sps30_write_then_read(struct sps30_state *state, u8 *txbuf,
|
|
++ int txsize, u8 *rxbuf, int rxsize)
|
|
++{
|
|
++ int ret;
|
|
++
|
|
++ /*
|
|
++ * Sensor does not support repeated start so instead of
|
|
++ * sending two i2c messages in a row we just send one by one.
|
|
++ */
|
|
++ ret = i2c_master_send(state->client, txbuf, txsize);
|
|
++ if (ret != txsize)
|
|
++ return ret < 0 ? ret : -EIO;
|
|
++
|
|
++ if (!rxbuf)
|
|
++ return 0;
|
|
++
|
|
++ ret = i2c_master_recv(state->client, rxbuf, rxsize);
|
|
++ if (ret != rxsize)
|
|
++ return ret < 0 ? ret : -EIO;
|
|
++
|
|
++ return 0;
|
|
++}
|
|
++
|
|
++static int sps30_do_cmd(struct sps30_state *state, u16 cmd, u8 *data, int size)
|
|
++{
|
|
++ /*
|
|
++ * Internally sensor stores measurements in a following manner:
|
|
++ *
|
|
++ * PM1: upper two bytes, crc8, lower two bytes, crc8
|
|
++ * PM2P5: upper two bytes, crc8, lower two bytes, crc8
|
|
++ * PM4: upper two bytes, crc8, lower two bytes, crc8
|
|
++ * PM10: upper two bytes, crc8, lower two bytes, crc8
|
|
++ *
|
|
++ * What follows next are number concentration measurements and
|
|
++ * typical particle size measurement which we omit.
|
|
++ */
|
|
++ u8 buf[SPS30_MAX_READ_SIZE] = { cmd >> 8, cmd };
|
|
++ int i, ret = 0;
|
|
++
|
|
++ switch (cmd) {
|
|
++ case SPS30_START_MEAS:
|
|
++ buf[2] = 0x03;
|
|
++ buf[3] = 0x00;
|
|
++ buf[4] = crc8(sps30_crc8_table, &buf[2], 2, CRC8_INIT_VALUE);
|
|
++ ret = sps30_write_then_read(state, buf, 5, NULL, 0);
|
|
++ break;
|
|
++ case SPS30_STOP_MEAS:
|
|
++ case SPS30_RESET:
|
|
++ ret = sps30_write_then_read(state, buf, 2, NULL, 0);
|
|
++ break;
|
|
++ case SPS30_READ_DATA_READY_FLAG:
|
|
++ case SPS30_READ_DATA:
|
|
++ case SPS30_READ_SERIAL:
|
|
++ /* every two data bytes are checksummed */
|
|
++ size += size / 2;
|
|
++ ret = sps30_write_then_read(state, buf, 2, buf, size);
|
|
++ break;
|
|
++ }
|
|
++
|
|
++ if (ret)
|
|
++ return ret;
|
|
++
|
|
++ /* validate received data and strip off crc bytes */
|
|
++ for (i = 0; i < size; i += 3) {
|
|
++ u8 crc = crc8(sps30_crc8_table, &buf[i], 2, CRC8_INIT_VALUE);
|
|
++
|
|
++ if (crc != buf[i + 2]) {
|
|
++ dev_err(&state->client->dev,
|
|
++ "data integrity check failed\n");
|
|
++ return -EIO;
|
|
++ }
|
|
++
|
|
++ *data++ = buf[i];
|
|
++ *data++ = buf[i + 1];
|
|
++ }
|
|
++
|
|
++ return 0;
|
|
++}
|
|
++
|
|
++static s32 sps30_float_to_int_clamped(const u8 *fp)
|
|
++{
|
|
++ int val = get_unaligned_be32(fp);
|
|
++ int mantissa = val & GENMASK(22, 0);
|
|
++ /* this is fine since passed float is always non-negative */
|
|
++ int exp = val >> 23;
|
|
++ int fraction, shift;
|
|
++
|
|
++ /* special case 0 */
|
|
++ if (!exp && !mantissa)
|
|
++ return 0;
|
|
++
|
|
++ exp -= 127;
|
|
++ if (exp < 0) {
|
|
++ /* return values ranging from 1 to 99 */
|
|
++ return ((((1 << 23) + mantissa) * 100) >> 23) >> (-exp);
|
|
++ }
|
|
++
|
|
++ /* return values ranging from 100 to 300000 */
|
|
++ shift = 23 - exp;
|
|
++ val = (1 << exp) + (mantissa >> shift);
|
|
++ if (val >= SPS30_MAX_PM)
|
|
++ return SPS30_MAX_PM * 100;
|
|
++
|
|
++ fraction = mantissa & GENMASK(shift - 1, 0);
|
|
++
|
|
++ return val * 100 + ((fraction * 100) >> shift);
|
|
++}
|
|
++
|
|
++static int sps30_do_meas(struct sps30_state *state, s32 *data, int size)
|
|
++{
|
|
++ int i, ret, tries = 5;
|
|
++ u8 tmp[16];
|
|
++
|
|
++ while (tries--) {
|
|
++ ret = sps30_do_cmd(state, SPS30_READ_DATA_READY_FLAG, tmp, 2);
|
|
++ if (ret)
|
|
++ return -EIO;
|
|
++
|
|
++ /* new measurements ready to be read */
|
|
++ if (tmp[1] == 1)
|
|
++ break;
|
|
++
|
|
++ msleep_interruptible(300);
|
|
++ }
|
|
++
|
|
++ if (!tries)
|
|
++ return -ETIMEDOUT;
|
|
++
|
|
++ ret = sps30_do_cmd(state, SPS30_READ_DATA, tmp, sizeof(int) * size);
|
|
++ if (ret)
|
|
++ return ret;
|
|
++
|
|
++ for (i = 0; i < size; i++)
|
|
++ data[i] = sps30_float_to_int_clamped(&tmp[4 * i]);
|
|
++
|
|
++ return 0;
|
|
++}
|
|
++
|
|
++static irqreturn_t sps30_trigger_handler(int irq, void *p)
|
|
++{
|
|
++ struct iio_poll_func *pf = p;
|
|
++ struct iio_dev *indio_dev = pf->indio_dev;
|
|
++ struct sps30_state *state = iio_priv(indio_dev);
|
|
++ int ret;
|
|
++ s32 data[4 + 2]; /* PM1, PM2P5, PM4, PM10, timestamp */
|
|
++
|
|
++ mutex_lock(&state->lock);
|
|
++ ret = sps30_do_meas(state, data, 4);
|
|
++ mutex_unlock(&state->lock);
|
|
++ if (ret)
|
|
++ goto err;
|
|
++
|
|
++ iio_push_to_buffers_with_timestamp(indio_dev, data,
|
|
++ iio_get_time_ns(indio_dev));
|
|
++err:
|
|
++ iio_trigger_notify_done(indio_dev->trig);
|
|
++
|
|
++ return IRQ_HANDLED;
|
|
++}
|
|
++
|
|
++static int sps30_read_raw(struct iio_dev *indio_dev,
|
|
++ struct iio_chan_spec const *chan,
|
|
++ int *val, int *val2, long mask)
|
|
++{
|
|
++ struct sps30_state *state = iio_priv(indio_dev);
|
|
++ int data[4], ret = -EINVAL;
|
|
++
|
|
++ switch (mask) {
|
|
++ case IIO_CHAN_INFO_PROCESSED:
|
|
++ switch (chan->type) {
|
|
++ case IIO_MASSCONCENTRATION:
|
|
++ mutex_lock(&state->lock);
|
|
++ /* read up to the number of bytes actually needed */
|
|
++ switch (chan->channel2) {
|
|
++ case IIO_MOD_PM1:
|
|
++ ret = sps30_do_meas(state, data, 1);
|
|
++ break;
|
|
++ case IIO_MOD_PM2P5:
|
|
++ ret = sps30_do_meas(state, data, 2);
|
|
++ break;
|
|
++ case IIO_MOD_PM4:
|
|
++ ret = sps30_do_meas(state, data, 3);
|
|
++ break;
|
|
++ case IIO_MOD_PM10:
|
|
++ ret = sps30_do_meas(state, data, 4);
|
|
++ break;
|
|
++ }
|
|
++ mutex_unlock(&state->lock);
|
|
++ if (ret)
|
|
++ return ret;
|
|
++
|
|
++ *val = data[chan->address] / 100;
|
|
++ *val2 = (data[chan->address] % 100) * 10000;
|
|
++
|
|
++ return IIO_VAL_INT_PLUS_MICRO;
|
|
++ default:
|
|
++ return -EINVAL;
|
|
++ }
|
|
++ case IIO_CHAN_INFO_SCALE:
|
|
++ switch (chan->type) {
|
|
++ case IIO_MASSCONCENTRATION:
|
|
++ switch (chan->channel2) {
|
|
++ case IIO_MOD_PM1:
|
|
++ case IIO_MOD_PM2P5:
|
|
++ case IIO_MOD_PM4:
|
|
++ case IIO_MOD_PM10:
|
|
++ *val = 0;
|
|
++ *val2 = 10000;
|
|
++
|
|
++ return IIO_VAL_INT_PLUS_MICRO;
|
|
++ }
|
|
++ default:
|
|
++ return -EINVAL;
|
|
++ }
|
|
++ }
|
|
++
|
|
++ return -EINVAL;
|
|
++}
|
|
++
|
|
++static const struct iio_info sps30_info = {
|
|
++ .read_raw = sps30_read_raw,
|
|
++};
|
|
++
|
|
++#define SPS30_CHAN(_index, _mod) { \
|
|
++ .type = IIO_MASSCONCENTRATION, \
|
|
++ .modified = 1, \
|
|
++ .channel2 = IIO_MOD_ ## _mod, \
|
|
++ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \
|
|
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
|
|
++ .address = _mod, \
|
|
++ .scan_index = _index, \
|
|
++ .scan_type = { \
|
|
++ .sign = 'u', \
|
|
++ .realbits = 19, \
|
|
++ .storagebits = 32, \
|
|
++ .endianness = IIO_CPU, \
|
|
++ }, \
|
|
++}
|
|
++
|
|
++static const struct iio_chan_spec sps30_channels[] = {
|
|
++ SPS30_CHAN(0, PM1),
|
|
++ SPS30_CHAN(1, PM2P5),
|
|
++ SPS30_CHAN(2, PM4),
|
|
++ SPS30_CHAN(3, PM10),
|
|
++ IIO_CHAN_SOFT_TIMESTAMP(4),
|
|
++};
|
|
++
|
|
++static void sps30_stop_meas(void *data)
|
|
++{
|
|
++ struct sps30_state *state = data;
|
|
++
|
|
++ sps30_do_cmd(state, SPS30_STOP_MEAS, NULL, 0);
|
|
++}
|
|
++
|
|
++static const unsigned long sps30_scan_masks[] = { 0x0f, 0x00 };
|
|
++
|
|
++static int sps30_probe(struct i2c_client *client)
|
|
++{
|
|
++ struct iio_dev *indio_dev;
|
|
++ struct sps30_state *state;
|
|
++ u8 buf[32];
|
|
++ int ret;
|
|
++
|
|
++ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
|
++ return -EOPNOTSUPP;
|
|
++
|
|
++ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*state));
|
|
++ if (!indio_dev)
|
|
++ return -ENOMEM;
|
|
++
|
|
++ state = iio_priv(indio_dev);
|
|
++ i2c_set_clientdata(client, indio_dev);
|
|
++ state->client = client;
|
|
++ indio_dev->dev.parent = &client->dev;
|
|
++ indio_dev->info = &sps30_info;
|
|
++ indio_dev->name = client->name;
|
|
++ indio_dev->channels = sps30_channels;
|
|
++ indio_dev->num_channels = ARRAY_SIZE(sps30_channels);
|
|
++ indio_dev->modes = INDIO_DIRECT_MODE;
|
|
++ indio_dev->available_scan_masks = sps30_scan_masks;
|
|
++
|
|
++ mutex_init(&state->lock);
|
|
++ crc8_populate_msb(sps30_crc8_table, SPS30_CRC8_POLYNOMIAL);
|
|
++
|
|
++ ret = sps30_do_cmd(state, SPS30_RESET, NULL, 0);
|
|
++ if (ret) {
|
|
++ dev_err(&client->dev, "failed to reset device\n");
|
|
++ return ret;
|
|
++ }
|
|
++ msleep(300);
|
|
++ /*
|
|
++ * Power-on-reset causes sensor to produce some glitch on i2c bus and
|
|
++ * some controllers end up in error state. Recover simply by placing
|
|
++ * some data on the bus, for example STOP_MEAS command, which
|
|
++ * is NOP in this case.
|
|
++ */
|
|
++ sps30_do_cmd(state, SPS30_STOP_MEAS, NULL, 0);
|
|
++
|
|
++ ret = sps30_do_cmd(state, SPS30_READ_SERIAL, buf, sizeof(buf));
|
|
++ if (ret) {
|
|
++ dev_err(&client->dev, "failed to read serial number\n");
|
|
++ return ret;
|
|
++ }
|
|
++ /* returned serial number is already NUL terminated */
|
|
++ dev_info(&client->dev, "serial number: %s\n", buf);
|
|
++
|
|
++ ret = sps30_do_cmd(state, SPS30_START_MEAS, NULL, 0);
|
|
++ if (ret) {
|
|
++ dev_err(&client->dev, "failed to start measurement\n");
|
|
++ return ret;
|
|
++ }
|
|
++
|
|
++ ret = devm_add_action_or_reset(&client->dev, sps30_stop_meas, state);
|
|
++ if (ret)
|
|
++ return ret;
|
|
++
|
|
++ ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, NULL,
|
|
++ sps30_trigger_handler, NULL);
|
|
++ if (ret)
|
|
++ return ret;
|
|
++
|
|
++ return devm_iio_device_register(&client->dev, indio_dev);
|
|
++}
|
|
++
|
|
++static const struct i2c_device_id sps30_id[] = {
|
|
++ { "sps30" },
|
|
++ { }
|
|
++};
|
|
++MODULE_DEVICE_TABLE(i2c, sps30_id);
|
|
++
|
|
++static const struct of_device_id sps30_of_match[] = {
|
|
++ { .compatible = "sensirion,sps30" },
|
|
++ { }
|
|
++};
|
|
++MODULE_DEVICE_TABLE(of, sps30_of_match);
|
|
++
|
|
++static struct i2c_driver sps30_driver = {
|
|
++ .driver = {
|
|
++ .name = "sps30",
|
|
++ .of_match_table = sps30_of_match,
|
|
++ },
|
|
++ .id_table = sps30_id,
|
|
++ .probe_new = sps30_probe,
|
|
++};
|
|
++module_i2c_driver(sps30_driver);
|
|
++
|
|
++MODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>");
|
|
++MODULE_DESCRIPTION("Sensirion SPS30 particulate matter sensor driver");
|
|
++MODULE_LICENSE("GPL v2");
|
|
diff --git a/target/linux/generic/backport-4.19/501-v5.1-iio-chemical-sps30-add-support-for-self-cleaning.patch b/target/linux/generic/backport-4.19/501-v5.1-iio-chemical-sps30-add-support-for-self-cleaning.patch
|
|
new file mode 100644
|
|
index 0000000000..7054fb0313
|
|
--- /dev/null
|
|
+++ b/target/linux/generic/backport-4.19/501-v5.1-iio-chemical-sps30-add-support-for-self-cleaning.patch
|
|
@@ -0,0 +1,100 @@
|
|
+From c546d49656143855093c7b7fde60866e6e23a69d Mon Sep 17 00:00:00 2001
|
|
+From: Tomasz Duszynski <tduszyns@gmail.com>
|
|
+Date: Tue, 18 Dec 2018 21:28:09 +0100
|
|
+Subject: [PATCH] iio: chemical: sps30: add support for self cleaning
|
|
+
|
|
+Self cleaning is especially useful in cases where sensor undergoes
|
|
+frequent power on/off cycles. In such scenarios it is recommended to
|
|
+turn self cleaning at least once per week in order to maintain reliable
|
|
+measurements.
|
|
+
|
|
+Self cleaning is activated by writing 1 to a dedicated attribute.
|
|
+Internal fan accelerates to its maximum speed and keeps spinning
|
|
+for about 10 seconds blowing out accumulated dust.
|
|
+
|
|
+Signed-off-by: Tomasz Duszynski <tduszyns@gmail.com>
|
|
+Tested-by: Andreas Brauchli <andreas.brauchli@sensirion.com>
|
|
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
+---
|
|
+ Documentation/ABI/testing/sysfs-bus-iio-sps30 | 8 +++++
|
|
+ drivers/iio/chemical/sps30.c | 35 ++++++++++++++++++-
|
|
+ 2 files changed, 42 insertions(+), 1 deletion(-)
|
|
+ create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-sps30
|
|
+
|
|
+--- /dev/null
|
|
++++ b/Documentation/ABI/testing/sysfs-bus-iio-sps30
|
|
+@@ -0,0 +1,8 @@
|
|
++What: /sys/bus/iio/devices/iio:deviceX/start_cleaning
|
|
++Date: December 2018
|
|
++KernelVersion: 4.22
|
|
++Contact: linux-iio@vger.kernel.org
|
|
++Description:
|
|
++ Writing 1 starts sensor self cleaning. Internal fan accelerates
|
|
++ to its maximum speed and keeps spinning for about 10 seconds in
|
|
++ order to blow out accumulated dust.
|
|
+--- a/drivers/iio/chemical/sps30.c
|
|
++++ b/drivers/iio/chemical/sps30.c
|
|
+@@ -7,7 +7,6 @@
|
|
+ * I2C slave address: 0x69
|
|
+ *
|
|
+ * TODO:
|
|
+- * - support for turning on fan cleaning
|
|
+ * - support for reading/setting auto cleaning interval
|
|
+ */
|
|
+
|
|
+@@ -37,6 +36,7 @@
|
|
+ #define SPS30_READ_DATA_READY_FLAG 0x0202
|
|
+ #define SPS30_READ_DATA 0x0300
|
|
+ #define SPS30_READ_SERIAL 0xd033
|
|
++#define SPS30_START_FAN_CLEANING 0x5607
|
|
+
|
|
+ enum {
|
|
+ PM1,
|
|
+@@ -104,6 +104,7 @@ static int sps30_do_cmd(struct sps30_sta
|
|
+ break;
|
|
+ case SPS30_STOP_MEAS:
|
|
+ case SPS30_RESET:
|
|
++ case SPS30_START_FAN_CLEANING:
|
|
+ ret = sps30_write_then_read(state, buf, 2, NULL, 0);
|
|
+ break;
|
|
+ case SPS30_READ_DATA_READY_FLAG:
|
|
+@@ -275,7 +276,39 @@ static int sps30_read_raw(struct iio_dev
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
++static ssize_t start_cleaning_store(struct device *dev,
|
|
++ struct device_attribute *attr,
|
|
++ const char *buf, size_t len)
|
|
++{
|
|
++ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
|
++ struct sps30_state *state = iio_priv(indio_dev);
|
|
++ int val, ret;
|
|
++
|
|
++ if (kstrtoint(buf, 0, &val) || val != 1)
|
|
++ return -EINVAL;
|
|
++
|
|
++ mutex_lock(&state->lock);
|
|
++ ret = sps30_do_cmd(state, SPS30_START_FAN_CLEANING, NULL, 0);
|
|
++ mutex_unlock(&state->lock);
|
|
++ if (ret)
|
|
++ return ret;
|
|
++
|
|
++ return len;
|
|
++}
|
|
++
|
|
++static IIO_DEVICE_ATTR_WO(start_cleaning, 0);
|
|
++
|
|
++static struct attribute *sps30_attrs[] = {
|
|
++ &iio_dev_attr_start_cleaning.dev_attr.attr,
|
|
++ NULL
|
|
++};
|
|
++
|
|
++static const struct attribute_group sps30_attr_group = {
|
|
++ .attrs = sps30_attrs,
|
|
++};
|
|
++
|
|
+ static const struct iio_info sps30_info = {
|
|
++ .attrs = &sps30_attr_group,
|
|
+ .read_raw = sps30_read_raw,
|
|
+ };
|
|
+
|
|
diff --git a/target/linux/generic/backport-4.19/502-v5.1-iio-chemical-sps30-allow-changing-self-cleaning-peri.patch b/target/linux/generic/backport-4.19/502-v5.1-iio-chemical-sps30-allow-changing-self-cleaning-peri.patch
|
|
new file mode 100644
|
|
index 0000000000..3a1335ba44
|
|
--- /dev/null
|
|
+++ b/target/linux/generic/backport-4.19/502-v5.1-iio-chemical-sps30-allow-changing-self-cleaning-peri.patch
|
|
@@ -0,0 +1,293 @@
|
|
+From 62129a0849d27cc94ced832bcf9dcde283dcbe08 Mon Sep 17 00:00:00 2001
|
|
+From: Tomasz Duszynski <tduszyns@gmail.com>
|
|
+Date: Tue, 15 Jan 2019 20:00:06 +0100
|
|
+Subject: [PATCH] iio: chemical: sps30: allow changing self cleaning period
|
|
+
|
|
+Sensor can periodically trigger self cleaning. Period can be changed by
|
|
+writing a new value to a dedicated attribute. Upon attribute read
|
|
+current period gets returned.
|
|
+
|
|
+Signed-off-by: Tomasz Duszynski <tduszyns@gmail.com>
|
|
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
+---
|
|
+ Documentation/ABI/testing/sysfs-bus-iio-sps30 | 20 +++
|
|
+ drivers/iio/chemical/sps30.c | 143 +++++++++++++++---
|
|
+ 2 files changed, 145 insertions(+), 18 deletions(-)
|
|
+
|
|
+--- a/Documentation/ABI/testing/sysfs-bus-iio-sps30
|
|
++++ b/Documentation/ABI/testing/sysfs-bus-iio-sps30
|
|
+@@ -6,3 +6,23 @@ Description:
|
|
+ Writing 1 starts sensor self cleaning. Internal fan accelerates
|
|
+ to its maximum speed and keeps spinning for about 10 seconds in
|
|
+ order to blow out accumulated dust.
|
|
++
|
|
++What: /sys/bus/iio/devices/iio:deviceX/cleaning_period
|
|
++Date: January 2019
|
|
++KernelVersion: 5.1
|
|
++Contact: linux-iio@vger.kernel.org
|
|
++Description:
|
|
++ Sensor is capable of triggering self cleaning periodically.
|
|
++ Period can be changed by writing a new value here. Upon reading
|
|
++ the current one is returned. Units are seconds.
|
|
++
|
|
++ Writing 0 disables periodical self cleaning entirely.
|
|
++
|
|
++What: /sys/bus/iio/devices/iio:deviceX/cleaning_period_available
|
|
++Date: January 2019
|
|
++KernelVersion: 5.1
|
|
++Contact: linux-iio@vger.kernel.org
|
|
++Description:
|
|
++ The range of available values in seconds represented as the
|
|
++ minimum value, the step and the maximum value, all enclosed in
|
|
++ square brackets.
|
|
+--- a/drivers/iio/chemical/sps30.c
|
|
++++ b/drivers/iio/chemical/sps30.c
|
|
+@@ -5,9 +5,6 @@
|
|
+ * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
|
|
+ *
|
|
+ * I2C slave address: 0x69
|
|
+- *
|
|
+- * TODO:
|
|
+- * - support for reading/setting auto cleaning interval
|
|
+ */
|
|
+
|
|
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
+@@ -21,6 +18,7 @@
|
|
+ #include <linux/iio/sysfs.h>
|
|
+ #include <linux/iio/trigger_consumer.h>
|
|
+ #include <linux/iio/triggered_buffer.h>
|
|
++#include <linux/kernel.h>
|
|
+ #include <linux/module.h>
|
|
+
|
|
+ #define SPS30_CRC8_POLYNOMIAL 0x31
|
|
+@@ -28,6 +26,9 @@
|
|
+ #define SPS30_MAX_READ_SIZE 48
|
|
+ /* sensor measures reliably up to 3000 ug / m3 */
|
|
+ #define SPS30_MAX_PM 3000
|
|
++/* minimum and maximum self cleaning periods in seconds */
|
|
++#define SPS30_AUTO_CLEANING_PERIOD_MIN 0
|
|
++#define SPS30_AUTO_CLEANING_PERIOD_MAX 604800
|
|
+
|
|
+ /* SPS30 commands */
|
|
+ #define SPS30_START_MEAS 0x0010
|
|
+@@ -37,6 +38,9 @@
|
|
+ #define SPS30_READ_DATA 0x0300
|
|
+ #define SPS30_READ_SERIAL 0xd033
|
|
+ #define SPS30_START_FAN_CLEANING 0x5607
|
|
++#define SPS30_AUTO_CLEANING_PERIOD 0x8004
|
|
++/* not a sensor command per se, used only to distinguish write from read */
|
|
++#define SPS30_READ_AUTO_CLEANING_PERIOD 0x8005
|
|
+
|
|
+ enum {
|
|
+ PM1,
|
|
+@@ -45,6 +49,11 @@ enum {
|
|
+ PM10,
|
|
+ };
|
|
+
|
|
++enum {
|
|
++ RESET,
|
|
++ MEASURING,
|
|
++};
|
|
++
|
|
+ struct sps30_state {
|
|
+ struct i2c_client *client;
|
|
+ /*
|
|
+@@ -52,6 +61,7 @@ struct sps30_state {
|
|
+ * Must be held whenever sequence of commands is to be executed.
|
|
+ */
|
|
+ struct mutex lock;
|
|
++ int state;
|
|
+ };
|
|
+
|
|
+ DECLARE_CRC8_TABLE(sps30_crc8_table);
|
|
+@@ -107,6 +117,9 @@ static int sps30_do_cmd(struct sps30_sta
|
|
+ case SPS30_START_FAN_CLEANING:
|
|
+ ret = sps30_write_then_read(state, buf, 2, NULL, 0);
|
|
+ break;
|
|
++ case SPS30_READ_AUTO_CLEANING_PERIOD:
|
|
++ buf[0] = SPS30_AUTO_CLEANING_PERIOD >> 8;
|
|
++ buf[1] = (u8)SPS30_AUTO_CLEANING_PERIOD;
|
|
+ case SPS30_READ_DATA_READY_FLAG:
|
|
+ case SPS30_READ_DATA:
|
|
+ case SPS30_READ_SERIAL:
|
|
+@@ -114,6 +127,15 @@ static int sps30_do_cmd(struct sps30_sta
|
|
+ size += size / 2;
|
|
+ ret = sps30_write_then_read(state, buf, 2, buf, size);
|
|
+ break;
|
|
++ case SPS30_AUTO_CLEANING_PERIOD:
|
|
++ buf[2] = data[0];
|
|
++ buf[3] = data[1];
|
|
++ buf[4] = crc8(sps30_crc8_table, &buf[2], 2, CRC8_INIT_VALUE);
|
|
++ buf[5] = data[2];
|
|
++ buf[6] = data[3];
|
|
++ buf[7] = crc8(sps30_crc8_table, &buf[5], 2, CRC8_INIT_VALUE);
|
|
++ ret = sps30_write_then_read(state, buf, 8, NULL, 0);
|
|
++ break;
|
|
+ }
|
|
+
|
|
+ if (ret)
|
|
+@@ -170,6 +192,14 @@ static int sps30_do_meas(struct sps30_st
|
|
+ int i, ret, tries = 5;
|
|
+ u8 tmp[16];
|
|
+
|
|
++ if (state->state == RESET) {
|
|
++ ret = sps30_do_cmd(state, SPS30_START_MEAS, NULL, 0);
|
|
++ if (ret)
|
|
++ return ret;
|
|
++
|
|
++ state->state = MEASURING;
|
|
++ }
|
|
++
|
|
+ while (tries--) {
|
|
+ ret = sps30_do_cmd(state, SPS30_READ_DATA_READY_FLAG, tmp, 2);
|
|
+ if (ret)
|
|
+@@ -276,6 +306,24 @@ static int sps30_read_raw(struct iio_dev
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
++static int sps30_do_cmd_reset(struct sps30_state *state)
|
|
++{
|
|
++ int ret;
|
|
++
|
|
++ ret = sps30_do_cmd(state, SPS30_RESET, NULL, 0);
|
|
++ msleep(300);
|
|
++ /*
|
|
++ * Power-on-reset causes sensor to produce some glitch on i2c bus and
|
|
++ * some controllers end up in error state. Recover simply by placing
|
|
++ * some data on the bus, for example STOP_MEAS command, which
|
|
++ * is NOP in this case.
|
|
++ */
|
|
++ sps30_do_cmd(state, SPS30_STOP_MEAS, NULL, 0);
|
|
++ state->state = RESET;
|
|
++
|
|
++ return ret;
|
|
++}
|
|
++
|
|
+ static ssize_t start_cleaning_store(struct device *dev,
|
|
+ struct device_attribute *attr,
|
|
+ const char *buf, size_t len)
|
|
+@@ -296,10 +344,82 @@ static ssize_t start_cleaning_store(stru
|
|
+ return len;
|
|
+ }
|
|
+
|
|
++static ssize_t cleaning_period_show(struct device *dev,
|
|
++ struct device_attribute *attr,
|
|
++ char *buf)
|
|
++{
|
|
++ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
|
++ struct sps30_state *state = iio_priv(indio_dev);
|
|
++ u8 tmp[4];
|
|
++ int ret;
|
|
++
|
|
++ mutex_lock(&state->lock);
|
|
++ ret = sps30_do_cmd(state, SPS30_READ_AUTO_CLEANING_PERIOD, tmp, 4);
|
|
++ mutex_unlock(&state->lock);
|
|
++ if (ret)
|
|
++ return ret;
|
|
++
|
|
++ return sprintf(buf, "%d\n", get_unaligned_be32(tmp));
|
|
++}
|
|
++
|
|
++static ssize_t cleaning_period_store(struct device *dev,
|
|
++ struct device_attribute *attr,
|
|
++ const char *buf, size_t len)
|
|
++{
|
|
++ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
|
++ struct sps30_state *state = iio_priv(indio_dev);
|
|
++ int val, ret;
|
|
++ u8 tmp[4];
|
|
++
|
|
++ if (kstrtoint(buf, 0, &val))
|
|
++ return -EINVAL;
|
|
++
|
|
++ if ((val < SPS30_AUTO_CLEANING_PERIOD_MIN) ||
|
|
++ (val > SPS30_AUTO_CLEANING_PERIOD_MAX))
|
|
++ return -EINVAL;
|
|
++
|
|
++ put_unaligned_be32(val, tmp);
|
|
++
|
|
++ mutex_lock(&state->lock);
|
|
++ ret = sps30_do_cmd(state, SPS30_AUTO_CLEANING_PERIOD, tmp, 0);
|
|
++ if (ret) {
|
|
++ mutex_unlock(&state->lock);
|
|
++ return ret;
|
|
++ }
|
|
++
|
|
++ msleep(20);
|
|
++
|
|
++ /*
|
|
++ * sensor requires reset in order to return up to date self cleaning
|
|
++ * period
|
|
++ */
|
|
++ ret = sps30_do_cmd_reset(state);
|
|
++ if (ret)
|
|
++ dev_warn(dev,
|
|
++ "period changed but reads will return the old value\n");
|
|
++
|
|
++ mutex_unlock(&state->lock);
|
|
++
|
|
++ return len;
|
|
++}
|
|
++
|
|
++static ssize_t cleaning_period_available_show(struct device *dev,
|
|
++ struct device_attribute *attr,
|
|
++ char *buf)
|
|
++{
|
|
++ return snprintf(buf, PAGE_SIZE, "[%d %d %d]\n",
|
|
++ SPS30_AUTO_CLEANING_PERIOD_MIN, 1,
|
|
++ SPS30_AUTO_CLEANING_PERIOD_MAX);
|
|
++}
|
|
++
|
|
+ static IIO_DEVICE_ATTR_WO(start_cleaning, 0);
|
|
++static IIO_DEVICE_ATTR_RW(cleaning_period, 0);
|
|
++static IIO_DEVICE_ATTR_RO(cleaning_period_available, 0);
|
|
+
|
|
+ static struct attribute *sps30_attrs[] = {
|
|
+ &iio_dev_attr_start_cleaning.dev_attr.attr,
|
|
++ &iio_dev_attr_cleaning_period.dev_attr.attr,
|
|
++ &iio_dev_attr_cleaning_period_available.dev_attr.attr,
|
|
+ NULL
|
|
+ };
|
|
+
|
|
+@@ -362,6 +482,7 @@ static int sps30_probe(struct i2c_client
|
|
+ state = iio_priv(indio_dev);
|
|
+ i2c_set_clientdata(client, indio_dev);
|
|
+ state->client = client;
|
|
++ state->state = RESET;
|
|
+ indio_dev->dev.parent = &client->dev;
|
|
+ indio_dev->info = &sps30_info;
|
|
+ indio_dev->name = client->name;
|
|
+@@ -373,19 +494,11 @@ static int sps30_probe(struct i2c_client
|
|
+ mutex_init(&state->lock);
|
|
+ crc8_populate_msb(sps30_crc8_table, SPS30_CRC8_POLYNOMIAL);
|
|
+
|
|
+- ret = sps30_do_cmd(state, SPS30_RESET, NULL, 0);
|
|
++ ret = sps30_do_cmd_reset(state);
|
|
+ if (ret) {
|
|
+ dev_err(&client->dev, "failed to reset device\n");
|
|
+ return ret;
|
|
+ }
|
|
+- msleep(300);
|
|
+- /*
|
|
+- * Power-on-reset causes sensor to produce some glitch on i2c bus and
|
|
+- * some controllers end up in error state. Recover simply by placing
|
|
+- * some data on the bus, for example STOP_MEAS command, which
|
|
+- * is NOP in this case.
|
|
+- */
|
|
+- sps30_do_cmd(state, SPS30_STOP_MEAS, NULL, 0);
|
|
+
|
|
+ ret = sps30_do_cmd(state, SPS30_READ_SERIAL, buf, sizeof(buf));
|
|
+ if (ret) {
|
|
+@@ -395,12 +508,6 @@ static int sps30_probe(struct i2c_client
|
|
+ /* returned serial number is already NUL terminated */
|
|
+ dev_info(&client->dev, "serial number: %s\n", buf);
|
|
+
|
|
+- ret = sps30_do_cmd(state, SPS30_START_MEAS, NULL, 0);
|
|
+- if (ret) {
|
|
+- dev_err(&client->dev, "failed to start measurement\n");
|
|
+- return ret;
|
|
+- }
|
|
+-
|
|
+ ret = devm_add_action_or_reset(&client->dev, sps30_stop_meas, state);
|
|
+ if (ret)
|
|
+ return ret;
|
|
diff --git a/target/linux/generic/backport-4.19/503-v5.1-iio-chemical-sps30-remove-printk-format-specifier.patch b/target/linux/generic/backport-4.19/503-v5.1-iio-chemical-sps30-remove-printk-format-specifier.patch
|
|
new file mode 100644
|
|
index 0000000000..b0fe5ac2e6
|
|
--- /dev/null
|
|
+++ b/target/linux/generic/backport-4.19/503-v5.1-iio-chemical-sps30-remove-printk-format-specifier.patch
|
|
@@ -0,0 +1,25 @@
|
|
+From 3fa30bf7004bb8069826ef85487f4753666a73da Mon Sep 17 00:00:00 2001
|
|
+From: Tomasz Duszynski <tduszyns@gmail.com>
|
|
+Date: Sat, 2 Feb 2019 10:00:03 +0100
|
|
+Subject: [PATCH] iio: chemical: sps30: remove printk format specifier
|
|
+
|
|
+pr_fmt is used by printk wrappers. There are not any in the driver
|
|
+code so remove the format specifier.
|
|
+
|
|
+Signed-off-by: Tomasz Duszynski <tduszyns@gmail.com>
|
|
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
+---
|
|
+ drivers/iio/chemical/sps30.c | 2 --
|
|
+ 1 file changed, 2 deletions(-)
|
|
+
|
|
+--- a/drivers/iio/chemical/sps30.c
|
|
++++ b/drivers/iio/chemical/sps30.c
|
|
+@@ -7,8 +7,6 @@
|
|
+ * I2C slave address: 0x69
|
|
+ */
|
|
+
|
|
+-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
+-
|
|
+ #include <asm/unaligned.h>
|
|
+ #include <linux/crc8.h>
|
|
+ #include <linux/delay.h>
|
|
diff --git a/target/linux/generic/backport-4.19/504-v5.1-iio-chemical-sps30-fix-a-loop-timeout-test.patch b/target/linux/generic/backport-4.19/504-v5.1-iio-chemical-sps30-fix-a-loop-timeout-test.patch
|
|
new file mode 100644
|
|
index 0000000000..c0aae35549
|
|
--- /dev/null
|
|
+++ b/target/linux/generic/backport-4.19/504-v5.1-iio-chemical-sps30-fix-a-loop-timeout-test.patch
|
|
@@ -0,0 +1,26 @@
|
|
+From 905889b4a34c753a538015f0b2cdaa0c9e3a4fd5 Mon Sep 17 00:00:00 2001
|
|
+From: Dan Carpenter <dan.carpenter@oracle.com>
|
|
+Date: Sat, 9 Feb 2019 12:03:52 +0300
|
|
+Subject: [PATCH] iio: chemical: sps30: fix a loop timeout test
|
|
+
|
|
+The "while (tries--) {" loop is a postop so it exits with "tries" set
|
|
+to -1.
|
|
+
|
|
+Fixes: 232e0f6ddeae ("iio: chemical: add support for Sensirion SPS30 sensor")
|
|
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
|
|
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
+---
|
|
+ drivers/iio/chemical/sps30.c | 2 +-
|
|
+ 1 file changed, 1 insertion(+), 1 deletion(-)
|
|
+
|
|
+--- a/drivers/iio/chemical/sps30.c
|
|
++++ b/drivers/iio/chemical/sps30.c
|
|
+@@ -210,7 +210,7 @@ static int sps30_do_meas(struct sps30_st
|
|
+ msleep_interruptible(300);
|
|
+ }
|
|
+
|
|
+- if (!tries)
|
|
++ if (tries == -1)
|
|
+ return -ETIMEDOUT;
|
|
+
|
|
+ ret = sps30_do_cmd(state, SPS30_READ_DATA, tmp, sizeof(int) * size);
|
|
diff --git a/target/linux/generic/backport-4.19/505-v5.1-iio-chemical-sps30-Supress-some-switch-fallthrough-w.patch b/target/linux/generic/backport-4.19/505-v5.1-iio-chemical-sps30-Supress-some-switch-fallthrough-w.patch
|
|
new file mode 100644
|
|
index 0000000000..08cc34ff40
|
|
--- /dev/null
|
|
+++ b/target/linux/generic/backport-4.19/505-v5.1-iio-chemical-sps30-Supress-some-switch-fallthrough-w.patch
|
|
@@ -0,0 +1,34 @@
|
|
+From 59b9bb0abca9efe47207301dbaf0d1beee2bd0f7 Mon Sep 17 00:00:00 2001
|
|
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
+Date: Sat, 9 Feb 2019 19:32:58 +0000
|
|
+Subject: [PATCH] iio:chemical:sps30 Supress some switch fallthrough warnings.
|
|
+
|
|
+Fixes warnings reported on linux-next but marking one path
|
|
+and adding an explicit return in the other.
|
|
+
|
|
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
+Cc: Andreas Brauchli <a.brauchli@elementarea.net>
|
|
+Acked-by: Tomasz Duszynski <tduszyns@gmail.com>
|
|
+---
|
|
+ drivers/iio/chemical/sps30.c | 3 +++
|
|
+ 1 file changed, 3 insertions(+)
|
|
+
|
|
+--- a/drivers/iio/chemical/sps30.c
|
|
++++ b/drivers/iio/chemical/sps30.c
|
|
+@@ -118,6 +118,7 @@ static int sps30_do_cmd(struct sps30_sta
|
|
+ case SPS30_READ_AUTO_CLEANING_PERIOD:
|
|
+ buf[0] = SPS30_AUTO_CLEANING_PERIOD >> 8;
|
|
+ buf[1] = (u8)SPS30_AUTO_CLEANING_PERIOD;
|
|
++ /* fall through */
|
|
+ case SPS30_READ_DATA_READY_FLAG:
|
|
+ case SPS30_READ_DATA:
|
|
+ case SPS30_READ_SERIAL:
|
|
+@@ -295,6 +296,8 @@ static int sps30_read_raw(struct iio_dev
|
|
+ *val2 = 10000;
|
|
+
|
|
+ return IIO_VAL_INT_PLUS_MICRO;
|
|
++ default:
|
|
++ return -EINVAL;
|
|
+ }
|
|
+ default:
|
|
+ return -EINVAL;
|
|
diff --git a/target/linux/generic/backport-4.19/506-v5.1-iio-chemical-sps30-Explicity-truncate-constant-by-ma.patch b/target/linux/generic/backport-4.19/506-v5.1-iio-chemical-sps30-Explicity-truncate-constant-by-ma.patch
|
|
new file mode 100644
|
|
index 0000000000..e1f4a3b635
|
|
--- /dev/null
|
|
+++ b/target/linux/generic/backport-4.19/506-v5.1-iio-chemical-sps30-Explicity-truncate-constant-by-ma.patch
|
|
@@ -0,0 +1,31 @@
|
|
+From 78b75ab3f8c9dfac563b81105a1b838ec37a940e Mon Sep 17 00:00:00 2001
|
|
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
+Date: Sun, 13 Oct 2019 10:55:15 +0100
|
|
+Subject: [PATCH] iio: chemical: sps30: Explicity truncate constant by masking
|
|
+
|
|
+When breaking up a constant to write to two 8 bit registers
|
|
+it isn't obvious to sparse that it was intentional.
|
|
+
|
|
+CHECK drivers/iio/chemical/sps30.c
|
|
+drivers/iio/chemical/sps30.c:120:30: warning: cast truncates bits from constant value (8004 becomes 4)
|
|
+
|
|
+So in the interests of minimising noisy warnings, let us add
|
|
+a mask.
|
|
+
|
|
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
+Acked-by: Tomasz Duszynski <tduszyns@gmail.com>
|
|
+---
|
|
+ drivers/iio/chemical/sps30.c | 2 +-
|
|
+ 1 file changed, 1 insertion(+), 1 deletion(-)
|
|
+
|
|
+--- a/drivers/iio/chemical/sps30.c
|
|
++++ b/drivers/iio/chemical/sps30.c
|
|
+@@ -117,7 +117,7 @@ static int sps30_do_cmd(struct sps30_sta
|
|
+ break;
|
|
+ case SPS30_READ_AUTO_CLEANING_PERIOD:
|
|
+ buf[0] = SPS30_AUTO_CLEANING_PERIOD >> 8;
|
|
+- buf[1] = (u8)SPS30_AUTO_CLEANING_PERIOD;
|
|
++ buf[1] = (u8)(SPS30_AUTO_CLEANING_PERIOD & 0xff);
|
|
+ /* fall through */
|
|
+ case SPS30_READ_DATA_READY_FLAG:
|
|
+ case SPS30_READ_DATA:
|
|
diff --git a/target/linux/generic/backport-4.19/507-v5.6-iio-chemical-sps30-fix-missing-triggered-buffer-depe.patch b/target/linux/generic/backport-4.19/507-v5.6-iio-chemical-sps30-fix-missing-triggered-buffer-depe.patch
|
|
new file mode 100644
|
|
index 0000000000..c2b999b1cb
|
|
--- /dev/null
|
|
+++ b/target/linux/generic/backport-4.19/507-v5.6-iio-chemical-sps30-fix-missing-triggered-buffer-depe.patch
|
|
@@ -0,0 +1,30 @@
|
|
+From 61338e27e2eef3bfcd3df5c39cec5b9dc10ba25c Mon Sep 17 00:00:00 2001
|
|
+From: =?UTF-8?q?Petr=20=C5=A0tetiar?= <ynezz@true.cz>
|
|
+Date: Sun, 23 Feb 2020 22:08:25 +0100
|
|
+Subject: [PATCH] iio: chemical: sps30: fix missing triggered buffer dependency
|
|
+MIME-Version: 1.0
|
|
+Content-Type: text/plain; charset=UTF-8
|
|
+Content-Transfer-Encoding: 8bit
|
|
+
|
|
+SPS30 uses triggered buffer, but the dependency is not specified in the
|
|
+Kconfig file. Fix this by selecting IIO_BUFFER and IIO_TRIGGERED_BUFFER
|
|
+config symbols.
|
|
+
|
|
+Cc: stable@vger.kernel.org
|
|
+Fixes: 232e0f6ddeae ("iio: chemical: add support for Sensirion SPS30 sensor")
|
|
+Signed-off-by: Petr Štetiar <ynezz@true.cz>
|
|
+---
|
|
+ drivers/iio/chemical/Kconfig | 2 ++
|
|
+ 1 file changed, 2 insertions(+)
|
|
+
|
|
+--- a/drivers/iio/chemical/Kconfig
|
|
++++ b/drivers/iio/chemical/Kconfig
|
|
+@@ -65,6 +65,8 @@ config SPS30
|
|
+ tristate "SPS30 particulate matter sensor"
|
|
+ depends on I2C
|
|
+ select CRC8
|
|
++ select IIO_BUFFER
|
|
++ select IIO_TRIGGERED_BUFFER
|
|
+ help
|
|
+ Say Y here to build support for the Sensirion SPS30 particulate
|
|
+ matter sensor.
|
|
diff --git a/target/linux/generic/backport-4.19/600-ipv6-addrconf-call-ipv6_mc_up-for-non-Ethernet-inter.patch b/target/linux/generic/backport-4.19/600-ipv6-addrconf-call-ipv6_mc_up-for-non-Ethernet-inter.patch
|
|
new file mode 100644
|
|
index 0000000000..d2d86f3df1
|
|
--- /dev/null
|
|
+++ b/target/linux/generic/backport-4.19/600-ipv6-addrconf-call-ipv6_mc_up-for-non-Ethernet-inter.patch
|
|
@@ -0,0 +1,71 @@
|
|
+From 82afdcd4ec3c8ca6551cbf7c43c09e2fd240487a Mon Sep 17 00:00:00 2001
|
|
+From: Hangbin Liu <liuhangbin@gmail.com>
|
|
+Date: Tue, 10 Mar 2020 15:27:37 +0800
|
|
+Subject: [PATCH] ipv6/addrconf: call ipv6_mc_up() for non-Ethernet interface
|
|
+MIME-Version: 1.0
|
|
+Content-Type: text/plain; charset=UTF-8
|
|
+Content-Transfer-Encoding: 8bit
|
|
+
|
|
+Rafał found an issue that for non-Ethernet interface, if we down and up
|
|
+frequently, the memory will be consumed slowly.
|
|
+
|
|
+The reason is we add allnodes/allrouters addressed in multicast list in
|
|
+ipv6_add_dev(). When link down, we call ipv6_mc_down(), store all multicast
|
|
+addresses via mld_add_delrec(). But when link up, we don't call ipv6_mc_up()
|
|
+for non-Ethernet interface to remove the addresses. This makes idev->mc_tomb
|
|
+getting bigger and bigger. The call stack looks like:
|
|
+
|
|
+addrconf_notify(NETDEV_REGISTER)
|
|
+ ipv6_add_dev
|
|
+ ipv6_dev_mc_inc(ff01::1)
|
|
+ ipv6_dev_mc_inc(ff02::1)
|
|
+ ipv6_dev_mc_inc(ff02::2)
|
|
+
|
|
+addrconf_notify(NETDEV_UP)
|
|
+ addrconf_dev_config
|
|
+ /* Alas, we support only Ethernet autoconfiguration. */
|
|
+ return;
|
|
+
|
|
+addrconf_notify(NETDEV_DOWN)
|
|
+ addrconf_ifdown
|
|
+ ipv6_mc_down
|
|
+ igmp6_group_dropped(ff02::2)
|
|
+ mld_add_delrec(ff02::2)
|
|
+ igmp6_group_dropped(ff02::1)
|
|
+ igmp6_group_dropped(ff01::1)
|
|
+
|
|
+After investigating, I can't found a rule to disable multicast on
|
|
+non-Ethernet interface. In RFC2460, the link could be Ethernet, PPP, ATM,
|
|
+tunnels, etc. In IPv4, it doesn't check the dev type when calls ip_mc_up()
|
|
+in inetdev_event(). Even for IPv6, we don't check the dev type and call
|
|
+ipv6_add_dev(), ipv6_dev_mc_inc() after register device.
|
|
+
|
|
+So I think it's OK to fix this memory consumer by calling ipv6_mc_up() for
|
|
+non-Ethernet interface.
|
|
+
|
|
+v2: Also check IFF_MULTICAST flag to make sure the interface supports
|
|
+ multicast
|
|
+
|
|
+Reported-by: Rafał Miłecki <zajec5@gmail.com>
|
|
+Tested-by: Rafał Miłecki <zajec5@gmail.com>
|
|
+Fixes: 74235a25c673 ("[IPV6] addrconf: Fix IPv6 on tuntap tunnels")
|
|
+Fixes: 1666d49e1d41 ("mld: do not remove mld souce list info when set link down")
|
|
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
|
|
+Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
+---
|
|
+ net/ipv6/addrconf.c | 4 ++++
|
|
+ 1 file changed, 4 insertions(+)
|
|
+
|
|
+--- a/net/ipv6/addrconf.c
|
|
++++ b/net/ipv6/addrconf.c
|
|
+@@ -3291,6 +3291,10 @@ static void addrconf_dev_config(struct n
|
|
+ (dev->type != ARPHRD_NONE) &&
|
|
+ (dev->type != ARPHRD_RAWIP)) {
|
|
+ /* Alas, we support only Ethernet autoconfiguration. */
|
|
++ idev = __in6_dev_get(dev);
|
|
++ if (!IS_ERR_OR_NULL(idev) && dev->flags & IFF_UP &&
|
|
++ dev->flags & IFF_MULTICAST)
|
|
++ ipv6_mc_up(idev);
|
|
+ return;
|
|
+ }
|
|
+
|
|
diff --git a/target/linux/generic/hack-4.19/550-loop-Report-EOPNOTSUPP-properly.patch b/target/linux/generic/hack-4.19/550-loop-Report-EOPNOTSUPP-properly.patch
|
|
index a3046cd8d1..023de0078d 100644
|
|
--- a/target/linux/generic/hack-4.19/550-loop-Report-EOPNOTSUPP-properly.patch
|
|
+++ b/target/linux/generic/hack-4.19/550-loop-Report-EOPNOTSUPP-properly.patch
|
|
@@ -26,7 +26,7 @@ Reviewed-by: Bart Van Assche <bvanassche@acm.org>
|
|
+ ret = errno_to_blk_status(cmd->ret);
|
|
goto end_io;
|
|
}
|
|
-
|
|
+
|
|
@@ -1904,7 +1904,10 @@ static void loop_handle_cmd(struct loop_
|
|
failed:
|
|
/* complete non-aio request */
|
|
diff --git a/target/linux/generic/hack-4.19/551-loop-Better-discard-support-for-block-devices.patch b/target/linux/generic/hack-4.19/551-loop-Better-discard-support-for-block-devices.patch
|
|
index 271389a4da..ac393e5f13 100644
|
|
--- a/target/linux/generic/hack-4.19/551-loop-Better-discard-support-for-block-devices.patch
|
|
+++ b/target/linux/generic/hack-4.19/551-loop-Better-discard-support-for-block-devices.patch
|
|
@@ -34,9 +34,9 @@ Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
|
|
struct file *file = lo->lo_backing_file;
|
|
+ struct request_queue *q = lo->lo_queue;
|
|
int ret;
|
|
-
|
|
+
|
|
mode |= FALLOC_FL_KEEP_SIZE;
|
|
-
|
|
+
|
|
- if ((!file->f_op->fallocate) || lo->lo_encrypt_key_size) {
|
|
+ if (!blk_queue_discard(q)) {
|
|
ret = -EOPNOTSUPP;
|
|
@@ -61,7 +61,7 @@ Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
|
|
+
|
|
+ blk_queue_max_write_zeroes_sectors(q,
|
|
+ backingq->limits.max_write_zeroes_sectors);
|
|
-
|
|
+
|
|
/*
|
|
* We use punch hole to reclaim the free space used by the
|
|
@@ -870,22 +886,24 @@ static void loop_config_discard(struct l
|
|
@@ -78,13 +78,13 @@ Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
|
|
- blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q);
|
|
- return;
|
|
- }
|
|
-
|
|
+
|
|
- q->limits.discard_granularity = inode->i_sb->s_blocksize;
|
|
- q->limits.discard_alignment = 0;
|
|
+ } else {
|
|
+ q->limits.discard_granularity = inode->i_sb->s_blocksize;
|
|
+ q->limits.discard_alignment = 0;
|
|
-
|
|
+
|
|
- blk_queue_max_discard_sectors(q, UINT_MAX >> 9);
|
|
- blk_queue_max_write_zeroes_sectors(q, UINT_MAX >> 9);
|
|
- blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
|
|
@@ -97,5 +97,5 @@ Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
|
|
+ else
|
|
+ blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q);
|
|
}
|
|
-
|
|
+
|
|
static void loop_unprepare_queue(struct loop_device *lo)
|
|
diff --git a/target/linux/generic/hack-4.19/645-netfilter-connmark-introduce-savedscp.patch b/target/linux/generic/hack-4.19/645-netfilter-connmark-introduce-savedscp.patch
|
|
deleted file mode 100644
|
|
index 0c4ef92c00..0000000000
|
|
--- a/target/linux/generic/hack-4.19/645-netfilter-connmark-introduce-savedscp.patch
|
|
+++ /dev/null
|
|
@@ -1,135 +0,0 @@
|
|
-From f171924dcf1d0b31fb7bd1cff113d7a1f7f05ec2 Mon Sep 17 00:00:00 2001
|
|
-From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
|
-Date: Sat, 23 Mar 2019 09:29:49 +0000
|
|
-Subject: [PATCH] netfilter: connmark: introduce savedscp
|
|
-
|
|
-savedscp is a method of storing the DSCP of an ip packet into conntrack
|
|
-mark. In combination with a suitable tc filter action (act_ctinfo) DSCP
|
|
-values are able to be stored in the mark on egress and restored on
|
|
-ingress across links that otherwise alter or bleach DSCP.
|
|
-
|
|
-This is useful for qdiscs such as CAKE which are able to shape according
|
|
-to policies based on DSCP.
|
|
-
|
|
-Ingress classification is traditionally a challenging task since
|
|
-iptables rules haven't yet run and tc filter/eBPF programs are pre-NAT
|
|
-lookups, hence are unable to see internal IPv4 addresses as used on the
|
|
-typical home masquerading gateway.
|
|
-
|
|
-x_tables CONNMARK savedscp action solves the problem of storing the DSCP
|
|
-to the conntrack mark in a way suitable for the new act_ctinfo tc action
|
|
-to restore.
|
|
-
|
|
-The savedsp option accepts 2 parameters, a 32bit 'dscpmask' and a 32bit
|
|
-'statemask'. The dscp mask must be a minimum of 6 contiguous bits and
|
|
-represents the area where the DSCP will be stored in the connmark. The
|
|
-state mask is a minimum 1 bit length mask that must not overlap with the
|
|
-dscpmask. It represents a flag which is set when the DSCP has been
|
|
-stored in the conntrack mark. This is useful to implement a 'one shot'
|
|
-iptables based classification where the 'complicated' iptables rules are
|
|
-only run once to classify the connection on initial (egress) packet and
|
|
-subsequent packets are all marked/restored with the same DSCP. A state
|
|
-mask of zero disables the setting of a status bit/s.
|
|
-
|
|
-example syntax with a suitably modified iptables user space application:
|
|
-
|
|
-iptables -A QOS_MARK_eth0 -t mangle -j CONNMARK --savedscp-mark 0xfc000000/0x01000000
|
|
-
|
|
-Would store the DSCP in the top 6 bits of the 32bit mark field, and use
|
|
-the LSB of the top byte as the 'DSCP has been stored' marker.
|
|
-
|
|
-|----0xFC----conntrack mark----000000---|
|
|
-| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0|
|
|
-| DSCP | unused | flag |unused |
|
|
-|-----------------------0x01---000000---|
|
|
- ^ ^
|
|
- | |
|
|
- ---| Conditional flag
|
|
- | set this when dscp
|
|
-|-ip diffserv-| stored in mark
|
|
-| 6 bits |
|
|
-|-------------|
|
|
-
|
|
-an identically configured tc action to restore looks like:
|
|
-
|
|
-tc filter show dev eth0 ingress
|
|
-filter parent ffff: protocol all pref 10 u32 chain 0
|
|
-filter parent ffff: protocol all pref 10 u32 chain 0 fh 800: ht divisor 1
|
|
-filter parent ffff: protocol all pref 10 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1 not_in_hw
|
|
- match 00000000/00000000 at 0
|
|
- action order 1: ctinfo zone 0 pipe
|
|
- index 2 ref 1 bind 1 dscp 0xfc000000/0x1000000
|
|
-
|
|
- action order 2: mirred (Egress Redirect to device ifb4eth0) stolen
|
|
- index 1 ref 1 bind 1
|
|
-
|
|
-|----0xFC----conntrack mark----000000---|
|
|
-| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0|
|
|
-| DSCP | unused | flag |unused |
|
|
-|-----------------------0x01---000000---|
|
|
- | |
|
|
- | |
|
|
- ---| Conditional flag
|
|
- v only restore if set
|
|
-|-ip diffserv-|
|
|
-| 6 bits |
|
|
-|-------------|
|
|
-
|
|
-Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
|
----
|
|
- include/uapi/linux/netfilter/xt_connmark.h | 3 ++-
|
|
- net/netfilter/xt_connmark.c | 17 +++++++++++++++++
|
|
- 2 files changed, 19 insertions(+), 1 deletion(-)
|
|
-
|
|
---- a/include/uapi/linux/netfilter/xt_connmark.h
|
|
-+++ b/include/uapi/linux/netfilter/xt_connmark.h
|
|
-@@ -16,7 +16,8 @@
|
|
- enum {
|
|
- XT_CONNMARK_SET = 0,
|
|
- XT_CONNMARK_SAVE,
|
|
-- XT_CONNMARK_RESTORE
|
|
-+ XT_CONNMARK_RESTORE,
|
|
-+ XT_CONNMARK_SAVEDSCP
|
|
- };
|
|
-
|
|
- enum {
|
|
---- a/net/netfilter/xt_connmark.c
|
|
-+++ b/net/netfilter/xt_connmark.c
|
|
-@@ -42,6 +42,7 @@ connmark_tg_shift(struct sk_buff *skb, c
|
|
- u_int32_t new_targetmark;
|
|
- struct nf_conn *ct;
|
|
- u_int32_t newmark;
|
|
-+ u_int8_t dscp;
|
|
-
|
|
- ct = nf_ct_get(skb, &ctinfo);
|
|
- if (ct == NULL)
|
|
-@@ -74,6 +75,21 @@ connmark_tg_shift(struct sk_buff *skb, c
|
|
- nf_conntrack_event_cache(IPCT_MARK, ct);
|
|
- }
|
|
- break;
|
|
-+ case XT_CONNMARK_SAVEDSCP:
|
|
-+ if (skb->protocol == htons(ETH_P_IP))
|
|
-+ dscp = ipv4_get_dsfield(ip_hdr(skb)) >> 2;
|
|
-+ else if (skb->protocol == htons(ETH_P_IPV6))
|
|
-+ dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2;
|
|
-+ else /* protocol doesn't have diffserv */
|
|
-+ break;
|
|
-+
|
|
-+ newmark = (ct->mark & ~info->ctmark) |
|
|
-+ (info->ctmask | (dscp << info->shift_bits));
|
|
-+ if (ct->mark != newmark) {
|
|
-+ ct->mark = newmark;
|
|
-+ nf_conntrack_event_cache(IPCT_MARK, ct);
|
|
-+ }
|
|
-+ break;
|
|
- case XT_CONNMARK_RESTORE:
|
|
- new_targetmark = (ct->mark & info->ctmask);
|
|
- if (info->shift_dir == D_SHIFT_RIGHT)
|
|
-@@ -86,6 +102,7 @@ connmark_tg_shift(struct sk_buff *skb, c
|
|
- skb->mark = newmark;
|
|
- break;
|
|
- }
|
|
-+out:
|
|
- return XT_CONTINUE;
|
|
- }
|
|
-
|
|
diff --git a/target/linux/generic/hack-4.19/645-netfilter-connmark-introduce-set-dscpmark.patch b/target/linux/generic/hack-4.19/645-netfilter-connmark-introduce-set-dscpmark.patch
|
|
new file mode 100644
|
|
index 0000000000..ca98187059
|
|
--- /dev/null
|
|
+++ b/target/linux/generic/hack-4.19/645-netfilter-connmark-introduce-set-dscpmark.patch
|
|
@@ -0,0 +1,212 @@
|
|
+From eda40b8c8c82e0f2789d6bc8bf63846dce2e8f32 Mon Sep 17 00:00:00 2001
|
|
+From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
|
+Date: Sat, 23 Mar 2019 09:29:49 +0000
|
|
+Subject: [PATCH] netfilter: connmark: introduce set-dscpmark
|
|
+
|
|
+set-dscpmark is a method of storing the DSCP of an ip packet into
|
|
+conntrack mark. In combination with a suitable tc filter action
|
|
+(act_ctinfo) DSCP values are able to be stored in the mark on egress and
|
|
+restored on ingress across links that otherwise alter or bleach DSCP.
|
|
+
|
|
+This is useful for qdiscs such as CAKE which are able to shape according
|
|
+to policies based on DSCP.
|
|
+
|
|
+Ingress classification is traditionally a challenging task since
|
|
+iptables rules haven't yet run and tc filter/eBPF programs are pre-NAT
|
|
+lookups, hence are unable to see internal IPv4 addresses as used on the
|
|
+typical home masquerading gateway.
|
|
+
|
|
+x_tables CONNMARK set-dscpmark target solves the problem of storing the
|
|
+DSCP to the conntrack mark in a way suitable for the new act_ctinfo tc
|
|
+action to restore.
|
|
+
|
|
+The set-dscpmark option accepts 2 parameters, a 32bit 'dscpmask' and a
|
|
+32bit 'statemask'. The dscp mask must be 6 contiguous bits and
|
|
+represents the area where the DSCP will be stored in the connmark. The
|
|
+state mask is a minimum 1 bit length mask that must not overlap with the
|
|
+dscpmask. It represents a flag which is set when the DSCP has been
|
|
+stored in the conntrack mark. This is useful to implement a 'one shot'
|
|
+iptables based classification where the 'complicated' iptables rules are
|
|
+only run once to classify the connection on initial (egress) packet and
|
|
+subsequent packets are all marked/restored with the same DSCP. A state
|
|
+mask of zero disables the setting of a status bit/s.
|
|
+
|
|
+example syntax with a suitably modified iptables user space application:
|
|
+
|
|
+iptables -A QOS_MARK_eth0 -t mangle -j CONNMARK --set-dscpmark 0xfc000000/0x01000000
|
|
+
|
|
+Would store the DSCP in the top 6 bits of the 32bit mark field, and use
|
|
+the LSB of the top byte as the 'DSCP has been stored' marker.
|
|
+
|
|
+|----0xFC----conntrack mark----000000---|
|
|
+| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0|
|
|
+| DSCP | unused | flag |unused |
|
|
+|-----------------------0x01---000000---|
|
|
+ ^ ^
|
|
+ | |
|
|
+ ---| Conditional flag
|
|
+ | set this when dscp
|
|
+|-ip diffserv-| stored in mark
|
|
+| 6 bits |
|
|
+|-------------|
|
|
+
|
|
+an identically configured tc action to restore looks like:
|
|
+
|
|
+tc filter show dev eth0 ingress
|
|
+filter parent ffff: protocol all pref 10 u32 chain 0
|
|
+filter parent ffff: protocol all pref 10 u32 chain 0 fh 800: ht divisor 1
|
|
+filter parent ffff: protocol all pref 10 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1: not_in_hw
|
|
+ match 00000000/00000000 at 0
|
|
+ action order 1: ctinfo zone 0 pipe
|
|
+ index 2 ref 1 bind 1 dscp 0xfc000000/0x1000000
|
|
+
|
|
+ action order 2: mirred (Egress Redirect to device ifb4eth0) stolen
|
|
+ index 1 ref 1 bind 1
|
|
+
|
|
+|----0xFC----conntrack mark----000000---|
|
|
+| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0|
|
|
+| DSCP | unused | flag |unused |
|
|
+|-----------------------0x01---000000---|
|
|
+ | |
|
|
+ | |
|
|
+ ---| Conditional flag
|
|
+ v only restore if set
|
|
+|-ip diffserv-|
|
|
+| 6 bits |
|
|
+|-------------|
|
|
+
|
|
+Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
|
+---
|
|
+ include/uapi/linux/netfilter/xt_connmark.h | 10 ++++
|
|
+ net/netfilter/xt_connmark.c | 55 ++++++++++++++++++----
|
|
+ 2 files changed, 57 insertions(+), 8 deletions(-)
|
|
+
|
|
+--- a/include/uapi/linux/netfilter/xt_connmark.h
|
|
++++ b/include/uapi/linux/netfilter/xt_connmark.h
|
|
+@@ -20,6 +20,11 @@ enum {
|
|
+ };
|
|
+
|
|
+ enum {
|
|
++ XT_CONNMARK_VALUE = (1 << 0),
|
|
++ XT_CONNMARK_DSCP = (1 << 1)
|
|
++};
|
|
++
|
|
++enum {
|
|
+ D_SHIFT_LEFT = 0,
|
|
+ D_SHIFT_RIGHT,
|
|
+ };
|
|
+@@ -34,6 +39,11 @@ struct xt_connmark_tginfo2 {
|
|
+ __u8 shift_dir, shift_bits, mode;
|
|
+ };
|
|
+
|
|
++struct xt_connmark_tginfo3 {
|
|
++ __u32 ctmark, ctmask, nfmask;
|
|
++ __u8 shift_dir, shift_bits, mode, func;
|
|
++};
|
|
++
|
|
+ struct xt_connmark_mtinfo1 {
|
|
+ __u32 mark, mask;
|
|
+ __u8 invert;
|
|
+--- a/net/netfilter/xt_connmark.c
|
|
++++ b/net/netfilter/xt_connmark.c
|
|
+@@ -36,12 +36,13 @@ MODULE_ALIAS("ipt_connmark");
|
|
+ MODULE_ALIAS("ip6t_connmark");
|
|
+
|
|
+ static unsigned int
|
|
+-connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
|
|
++connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo3 *info)
|
|
+ {
|
|
+ enum ip_conntrack_info ctinfo;
|
|
+ u_int32_t new_targetmark;
|
|
+ struct nf_conn *ct;
|
|
+ u_int32_t newmark;
|
|
++ u_int8_t dscp;
|
|
+
|
|
+ ct = nf_ct_get(skb, &ctinfo);
|
|
+ if (ct == NULL)
|
|
+@@ -49,12 +50,24 @@ connmark_tg_shift(struct sk_buff *skb, c
|
|
+
|
|
+ switch (info->mode) {
|
|
+ case XT_CONNMARK_SET:
|
|
+- newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
|
|
+- if (info->shift_dir == D_SHIFT_RIGHT)
|
|
+- newmark >>= info->shift_bits;
|
|
+- else
|
|
+- newmark <<= info->shift_bits;
|
|
++ newmark = ct->mark;
|
|
++ if (info->func & XT_CONNMARK_VALUE) {
|
|
++ newmark = (newmark & ~info->ctmask) ^ info->ctmark;
|
|
++ if (info->shift_dir == D_SHIFT_RIGHT)
|
|
++ newmark >>= info->shift_bits;
|
|
++ else
|
|
++ newmark <<= info->shift_bits;
|
|
++ } else if (info->func & XT_CONNMARK_DSCP) {
|
|
++ if (skb->protocol == htons(ETH_P_IP))
|
|
++ dscp = ipv4_get_dsfield(ip_hdr(skb)) >> 2;
|
|
++ else if (skb->protocol == htons(ETH_P_IPV6))
|
|
++ dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2;
|
|
++ else /* protocol doesn't have diffserv */
|
|
++ break;
|
|
+
|
|
++ newmark = (newmark & ~info->ctmark) |
|
|
++ (info->ctmask | (dscp << info->shift_bits));
|
|
++ }
|
|
+ if (ct->mark != newmark) {
|
|
+ ct->mark = newmark;
|
|
+ nf_conntrack_event_cache(IPCT_MARK, ct);
|
|
+@@ -93,20 +106,36 @@ static unsigned int
|
|
+ connmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
|
+ {
|
|
+ const struct xt_connmark_tginfo1 *info = par->targinfo;
|
|
+- const struct xt_connmark_tginfo2 info2 = {
|
|
++ const struct xt_connmark_tginfo3 info3 = {
|
|
+ .ctmark = info->ctmark,
|
|
+ .ctmask = info->ctmask,
|
|
+ .nfmask = info->nfmask,
|
|
+ .mode = info->mode,
|
|
++ .func = XT_CONNMARK_VALUE
|
|
+ };
|
|
+
|
|
+- return connmark_tg_shift(skb, &info2);
|
|
++ return connmark_tg_shift(skb, &info3);
|
|
+ }
|
|
+
|
|
+ static unsigned int
|
|
+ connmark_tg_v2(struct sk_buff *skb, const struct xt_action_param *par)
|
|
+ {
|
|
+ const struct xt_connmark_tginfo2 *info = par->targinfo;
|
|
++ const struct xt_connmark_tginfo3 info3 = {
|
|
++ .ctmark = info->ctmark,
|
|
++ .ctmask = info->ctmask,
|
|
++ .nfmask = info->nfmask,
|
|
++ .mode = info->mode,
|
|
++ .func = XT_CONNMARK_VALUE
|
|
++ };
|
|
++
|
|
++ return connmark_tg_shift(skb, &info3);
|
|
++}
|
|
++
|
|
++static unsigned int
|
|
++connmark_tg_v3(struct sk_buff *skb, const struct xt_action_param *par)
|
|
++{
|
|
++ const struct xt_connmark_tginfo3 *info = par->targinfo;
|
|
+
|
|
+ return connmark_tg_shift(skb, info);
|
|
+ }
|
|
+@@ -177,6 +206,16 @@ static struct xt_target connmark_tg_reg[
|
|
+ .targetsize = sizeof(struct xt_connmark_tginfo2),
|
|
+ .destroy = connmark_tg_destroy,
|
|
+ .me = THIS_MODULE,
|
|
++ },
|
|
++ {
|
|
++ .name = "CONNMARK",
|
|
++ .revision = 3,
|
|
++ .family = NFPROTO_UNSPEC,
|
|
++ .checkentry = connmark_tg_check,
|
|
++ .target = connmark_tg_v3,
|
|
++ .targetsize = sizeof(struct xt_connmark_tginfo3),
|
|
++ .destroy = connmark_tg_destroy,
|
|
++ .me = THIS_MODULE,
|
|
+ }
|
|
+ };
|
|
+
|
|
diff --git a/target/linux/generic/hack-4.19/702-phy_add_aneg_done_function.patch b/target/linux/generic/hack-4.19/702-phy_add_aneg_done_function.patch
|
|
index fe295906ee..a0e6484be8 100644
|
|
--- a/target/linux/generic/hack-4.19/702-phy_add_aneg_done_function.patch
|
|
+++ b/target/linux/generic/hack-4.19/702-phy_add_aneg_done_function.patch
|
|
@@ -1,6 +1,6 @@
|
|
--- a/include/linux/phy.h
|
|
+++ b/include/linux/phy.h
|
|
-@@ -548,6 +548,12 @@ struct phy_driver {
|
|
+@@ -555,6 +555,12 @@ struct phy_driver {
|
|
/* Determines the negotiated speed and duplex */
|
|
int (*read_status)(struct phy_device *phydev);
|
|
|
|
diff --git a/target/linux/generic/hack-4.19/902-debloat_proc.patch b/target/linux/generic/hack-4.19/902-debloat_proc.patch
|
|
index 1442cee8bb..0f4f445624 100644
|
|
--- a/target/linux/generic/hack-4.19/902-debloat_proc.patch
|
|
+++ b/target/linux/generic/hack-4.19/902-debloat_proc.patch
|
|
@@ -189,7 +189,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
}
|
|
--- a/kernel/irq/proc.c
|
|
+++ b/kernel/irq/proc.c
|
|
-@@ -333,6 +333,9 @@ void register_irq_proc(unsigned int irq,
|
|
+@@ -355,6 +355,9 @@ void register_irq_proc(unsigned int irq,
|
|
void __maybe_unused *irqp = (void *)(unsigned long) irq;
|
|
char name [MAX_NAMELEN];
|
|
|
|
@@ -199,7 +199,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip))
|
|
return;
|
|
|
|
-@@ -386,6 +389,9 @@ void unregister_irq_proc(unsigned int ir
|
|
+@@ -408,6 +411,9 @@ void unregister_irq_proc(unsigned int ir
|
|
{
|
|
char name [MAX_NAMELEN];
|
|
|
|
@@ -209,7 +209,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
if (!root_irq_dir || !desc->dir)
|
|
return;
|
|
#ifdef CONFIG_SMP
|
|
-@@ -424,6 +430,9 @@ void init_irq_proc(void)
|
|
+@@ -446,6 +452,9 @@ void init_irq_proc(void)
|
|
unsigned int irq;
|
|
struct irq_desc *desc;
|
|
|
|
diff --git a/target/linux/generic/pending-4.14/647-netfilter-nf_flow_table_hw-fix-incorrect-ethernet-ds.patch b/target/linux/generic/pending-4.14/647-netfilter-nf_flow_table_hw-fix-incorrect-ethernet-ds.patch
|
|
new file mode 100644
|
|
index 0000000000..a81445bb95
|
|
--- /dev/null
|
|
+++ b/target/linux/generic/pending-4.14/647-netfilter-nf_flow_table_hw-fix-incorrect-ethernet-ds.patch
|
|
@@ -0,0 +1,87 @@
|
|
+From: Konstantin Vasin <tempest921@gmail.com>
|
|
+Date: Mon, 9 Mar 2020 18:38:54 +0300
|
|
+Subject: [PATCH] netfilter: nf_flow_table_hw: fix incorrect ethernet dst
|
|
+ address
|
|
+
|
|
+Ethernet destination for original traffic takes the source ethernet
|
|
+address in the reply direction. For reply traffic, this takes
|
|
+the source ethernet address of the original destination.
|
|
+
|
|
+This fix is based on the upstream commit 1b67e506:
|
|
+("netfilter: nf_flow_table_offload: fix incorrect ethernet dst address")
|
|
+from wenxu <wenxu@ucloud.cn>
|
|
+
|
|
+Signed-off-by: Konstantin Vasin <tempest921@gmail.com>
|
|
+---
|
|
+
|
|
+--- a/net/netfilter/nf_flow_table_hw.c
|
|
++++ b/net/netfilter/nf_flow_table_hw.c
|
|
+@@ -24,17 +24,23 @@ struct flow_offload_hw {
|
|
+ struct flow_offload_hw_path dest;
|
|
+ };
|
|
+
|
|
+-static void flow_offload_check_ethernet(struct flow_offload_tuple *tuple,
|
|
++static void flow_offload_check_ethernet(struct flow_offload *flow,
|
|
++ enum flow_offload_tuple_dir dir,
|
|
+ struct flow_offload_hw_path *path)
|
|
+ {
|
|
+ struct net_device *dev = path->dev;
|
|
+ struct neighbour *n;
|
|
++ const void *daddr;
|
|
++ const struct dst_entry *dst_cache;
|
|
+
|
|
+ if (dev->type != ARPHRD_ETHER)
|
|
+ return;
|
|
+
|
|
+ memcpy(path->eth_src, path->dev->dev_addr, ETH_ALEN);
|
|
+- n = dst_neigh_lookup(tuple->dst_cache, &tuple->src_v4);
|
|
++
|
|
++ daddr = &flow->tuplehash[dir].tuple.src_v4;
|
|
++ dst_cache = flow->tuplehash[!dir].tuple.dst_cache;
|
|
++ n = dst_neigh_lookup(dst_cache, daddr);
|
|
+ if (!n)
|
|
+ return;
|
|
+
|
|
+@@ -44,17 +50,18 @@ static void flow_offload_check_ethernet(struct flow_offload_tuple *tuple,
|
|
+ }
|
|
+
|
|
+ static int flow_offload_check_path(struct net *net,
|
|
+- struct flow_offload_tuple *tuple,
|
|
++ struct flow_offload *flow,
|
|
++ enum flow_offload_tuple_dir dir,
|
|
+ struct flow_offload_hw_path *path)
|
|
+ {
|
|
+ struct net_device *dev;
|
|
+
|
|
+- dev = dev_get_by_index_rcu(net, tuple->iifidx);
|
|
++ dev = dev_get_by_index_rcu(net, flow->tuplehash[dir].tuple.iifidx);
|
|
+ if (!dev)
|
|
+ return -ENOENT;
|
|
+
|
|
+ path->dev = dev;
|
|
+- flow_offload_check_ethernet(tuple, path);
|
|
++ flow_offload_check_ethernet(flow, dir, path);
|
|
+
|
|
+ if (dev->netdev_ops->ndo_flow_offload_check)
|
|
+ return dev->netdev_ops->ndo_flow_offload_check(path);
|
|
+@@ -133,17 +140,14 @@ flow_offload_hw_prepare(struct net *net, struct flow_offload *flow)
|
|
+ {
|
|
+ struct flow_offload_hw_path src = {};
|
|
+ struct flow_offload_hw_path dest = {};
|
|
+- struct flow_offload_tuple *tuple;
|
|
+ struct flow_offload_hw *offload = NULL;
|
|
+
|
|
+ rcu_read_lock_bh();
|
|
+
|
|
+- tuple = &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple;
|
|
+- if (flow_offload_check_path(net, tuple, &src))
|
|
++ if (flow_offload_check_path(net, flow, FLOW_OFFLOAD_DIR_ORIGINAL, &src))
|
|
+ goto out;
|
|
+
|
|
+- tuple = &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple;
|
|
+- if (flow_offload_check_path(net, tuple, &dest))
|
|
++ if (flow_offload_check_path(net, flow, FLOW_OFFLOAD_DIR_REPLY, &dest))
|
|
+ goto out;
|
|
+
|
|
+ if (!src.dev->netdev_ops->ndo_flow_offload)
|
|
+
|
|
diff --git a/target/linux/generic/pending-4.14/648-netfilter-nf_flow_table_hw-check-the-status-of-dst_n.patch b/target/linux/generic/pending-4.14/648-netfilter-nf_flow_table_hw-check-the-status-of-dst_n.patch
|
|
new file mode 100644
|
|
index 0000000000..ed4a1e3a3e
|
|
--- /dev/null
|
|
+++ b/target/linux/generic/pending-4.14/648-netfilter-nf_flow_table_hw-check-the-status-of-dst_n.patch
|
|
@@ -0,0 +1,32 @@
|
|
+From: Konstantin Vasin <tempest921@gmail.com>
|
|
+Date: Mon, 9 Mar 2020 17:41:22 +0300
|
|
+Subject: [PATCH] netfilter: nf_flow_table_hw: check the status of
|
|
+ dst_neigh
|
|
+
|
|
+It's better to check the nud_state is VALID.
|
|
+If there is not neigh previos, the lookup will
|
|
+create a non NUD_VALID with 00:00:00:00:00:00 mac.
|
|
+
|
|
+This fix is based on the upstream commit f31ad71c44
|
|
+("netfilter: nf_flow_table_offload: check the status of dst_neigh")
|
|
+from wenxu <wenxu@ucloud.cn>
|
|
+
|
|
+Signed-off-by: Konstantin Vasin <tempest921@gmail.com>
|
|
+---
|
|
+
|
|
+index e831c8830e91..1238d675a316 100644
|
|
+--- a/net/netfilter/nf_flow_table_hw.c
|
|
++++ b/net/netfilter/nf_flow_table_hw.c
|
|
+@@ -44,8 +44,10 @@ static void flow_offload_check_ethernet(struct flow_offload *flow,
|
|
+ if (!n)
|
|
+ return;
|
|
+
|
|
+- memcpy(path->eth_dest, n->ha, ETH_ALEN);
|
|
+- path->flags |= FLOW_OFFLOAD_PATH_ETHERNET;
|
|
++ if (n->nud_state & NUD_VALID) {
|
|
++ memcpy(path->eth_dest, n->ha, ETH_ALEN);
|
|
++ path->flags |= FLOW_OFFLOAD_PATH_ETHERNET;
|
|
++ }
|
|
+ neigh_release(n);
|
|
+ }
|
|
+
|
|
diff --git a/target/linux/generic/pending-4.19/411-mtd-partial_eraseblock_write.patch b/target/linux/generic/pending-4.19/411-mtd-partial_eraseblock_write.patch
|
|
index bf9822fda8..f3a314ae02 100644
|
|
--- a/target/linux/generic/pending-4.19/411-mtd-partial_eraseblock_write.patch
|
|
+++ b/target/linux/generic/pending-4.19/411-mtd-partial_eraseblock_write.patch
|
|
@@ -114,8 +114,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
+ slave->mtd.erasesize = slave->mtd.size;
|
|
}
|
|
|
|
-- tmp = part_absolute_offset(parent) + slave->mtd.size;
|
|
-+ tmp = part_absolute_offset(parent) + slave->offset + slave->mtd.size;
|
|
+ tmp = part_absolute_offset(parent) + slave->offset + slave->mtd.size;
|
|
remainder = do_div(tmp, wr_alignment);
|
|
if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) {
|
|
- slave->mtd.flags &= ~MTD_WRITEABLE;
|
|
diff --git a/target/linux/generic/pending-4.19/450-mtd-spi-nor-allow-NOR-driver-to-write-fewer-bytes-th.patch b/target/linux/generic/pending-4.19/450-mtd-spi-nor-allow-NOR-driver-to-write-fewer-bytes-th.patch
|
|
index 6981c6d943..4d64fca90b 100644
|
|
--- a/target/linux/generic/pending-4.19/450-mtd-spi-nor-allow-NOR-driver-to-write-fewer-bytes-th.patch
|
|
+++ b/target/linux/generic/pending-4.19/450-mtd-spi-nor-allow-NOR-driver-to-write-fewer-bytes-th.patch
|
|
@@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
|
|
--- a/drivers/mtd/spi-nor/spi-nor.c
|
|
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
|
-@@ -1457,7 +1457,7 @@ static int spi_nor_write(struct mtd_info
|
|
+@@ -1459,7 +1459,7 @@ static int spi_nor_write(struct mtd_info
|
|
|
|
write_enable(nor);
|
|
ret = nor->write(nor, addr, page_remain, buf + i);
|
|
@@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
goto write_err;
|
|
written = ret;
|
|
|
|
-@@ -1466,13 +1466,6 @@ static int spi_nor_write(struct mtd_info
|
|
+@@ -1468,13 +1468,6 @@ static int spi_nor_write(struct mtd_info
|
|
goto write_err;
|
|
*retlen += written;
|
|
i += written;
|
|
diff --git a/target/linux/generic/pending-4.19/465-m25p80-mx-disable-software-protection.patch b/target/linux/generic/pending-4.19/465-m25p80-mx-disable-software-protection.patch
|
|
index 0c5d6cfa63..3172c223f2 100644
|
|
--- a/target/linux/generic/pending-4.19/465-m25p80-mx-disable-software-protection.patch
|
|
+++ b/target/linux/generic/pending-4.19/465-m25p80-mx-disable-software-protection.patch
|
|
@@ -8,7 +8,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
|
|
--- a/drivers/mtd/spi-nor/spi-nor.c
|
|
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
|
-@@ -2735,6 +2735,7 @@ static int spi_nor_init(struct spi_nor *
|
|
+@@ -2737,6 +2737,7 @@ static int spi_nor_init(struct spi_nor *
|
|
*/
|
|
if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
|
|
JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
|
|
diff --git a/target/linux/generic/pending-4.19/466-Revert-mtd-spi-nor-fix-Spansion-regressions-aliased-.patch b/target/linux/generic/pending-4.19/466-Revert-mtd-spi-nor-fix-Spansion-regressions-aliased-.patch
|
|
index fb6ae7df7b..f6a98af6ac 100644
|
|
--- a/target/linux/generic/pending-4.19/466-Revert-mtd-spi-nor-fix-Spansion-regressions-aliased-.patch
|
|
+++ b/target/linux/generic/pending-4.19/466-Revert-mtd-spi-nor-fix-Spansion-regressions-aliased-.patch
|
|
@@ -17,7 +17,7 @@ Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
|
|
|
|
--- a/drivers/mtd/spi-nor/spi-nor.c
|
|
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
|
-@@ -2737,6 +2737,7 @@ static int spi_nor_init(struct spi_nor *
|
|
+@@ -2739,6 +2739,7 @@ static int spi_nor_init(struct spi_nor *
|
|
JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
|
|
JEDEC_MFR(nor->info) == SNOR_MFR_MACRONIX ||
|
|
JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
|
|
@@ -25,7 +25,7 @@ Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
|
|
nor->info->flags & SPI_NOR_HAS_LOCK) {
|
|
write_enable(nor);
|
|
write_sr(nor, 0);
|
|
-@@ -2873,7 +2874,8 @@ int spi_nor_scan(struct spi_nor *nor, co
|
|
+@@ -2875,7 +2876,8 @@ int spi_nor_scan(struct spi_nor *nor, co
|
|
|
|
/* NOR protection support for STmicro/Micron chips and similar */
|
|
if (JEDEC_MFR(info) == SNOR_MFR_MICRON ||
|
|
diff --git a/target/linux/generic/pending-4.19/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch b/target/linux/generic/pending-4.19/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch
|
|
index 12d785856a..695c38cf0f 100644
|
|
--- a/target/linux/generic/pending-4.19/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch
|
|
+++ b/target/linux/generic/pending-4.19/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch
|
|
@@ -39,7 +39,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
depends on ARCH_AT91 || (ARM && COMPILE_TEST && !ARCH_EBSA110)
|
|
--- a/drivers/mtd/spi-nor/spi-nor.c
|
|
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
|
-@@ -2649,10 +2649,12 @@ static int spi_nor_select_erase(struct s
|
|
+@@ -2651,10 +2651,12 @@ static int spi_nor_select_erase(struct s
|
|
|
|
#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
|
|
/* prefer "small sector" erase if possible */
|
|
diff --git a/target/linux/generic/pending-4.19/479-mtd-spi-nor-add-xtx-xt25f128b.patch b/target/linux/generic/pending-4.19/479-mtd-spi-nor-add-xtx-xt25f128b.patch
|
|
index 664837928b..da60939bb3 100644
|
|
--- a/target/linux/generic/pending-4.19/479-mtd-spi-nor-add-xtx-xt25f128b.patch
|
|
+++ b/target/linux/generic/pending-4.19/479-mtd-spi-nor-add-xtx-xt25f128b.patch
|
|
@@ -30,7 +30,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|
|
|
--- a/drivers/mtd/spi-nor/spi-nor.c
|
|
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
|
-@@ -1273,6 +1273,9 @@ static const struct flash_info spi_nor_i
|
|
+@@ -1275,6 +1275,9 @@ static const struct flash_info spi_nor_i
|
|
/* XMC (Wuhan Xinxin Semiconductor Manufacturing Corp.) */
|
|
{ "XM25QH64A", INFO(0x207017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
|
{ "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
|
diff --git a/target/linux/generic/pending-4.19/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/pending-4.19/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
|
|
index c35aca8a18..cfdfe10836 100644
|
|
--- a/target/linux/generic/pending-4.19/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
|
|
+++ b/target/linux/generic/pending-4.19/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
|
|
@@ -185,7 +185,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
|
cfg->fc_flags |= RTF_REJECT;
|
|
|
|
if (rtm->rtm_type == RTN_LOCAL)
|
|
-@@ -5084,6 +5115,8 @@ static int ip6_route_dev_notify(struct n
|
|
+@@ -5085,6 +5116,8 @@ static int ip6_route_dev_notify(struct n
|
|
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
|
net->ipv6.ip6_prohibit_entry->dst.dev = dev;
|
|
net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev);
|
|
@@ -194,7 +194,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
|
net->ipv6.ip6_blk_hole_entry->dst.dev = dev;
|
|
net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
|
|
#endif
|
|
-@@ -5095,6 +5128,7 @@ static int ip6_route_dev_notify(struct n
|
|
+@@ -5096,6 +5129,7 @@ static int ip6_route_dev_notify(struct n
|
|
in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev);
|
|
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
|
in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev);
|
|
@@ -202,7 +202,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
|
in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev);
|
|
#endif
|
|
}
|
|
-@@ -5289,6 +5323,15 @@ static int __net_init ip6_route_net_init
|
|
+@@ -5290,6 +5324,15 @@ static int __net_init ip6_route_net_init
|
|
net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
|
|
dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst,
|
|
ip6_template_metrics, true);
|
|
@@ -218,7 +218,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
|
#endif
|
|
|
|
net->ipv6.sysctl.flush_delay = 0;
|
|
-@@ -5307,6 +5350,8 @@ out:
|
|
+@@ -5308,6 +5351,8 @@ out:
|
|
return ret;
|
|
|
|
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
|
@@ -227,7 +227,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
|
out_ip6_prohibit_entry:
|
|
kfree(net->ipv6.ip6_prohibit_entry);
|
|
out_ip6_null_entry:
|
|
-@@ -5327,6 +5372,7 @@ static void __net_exit ip6_route_net_exi
|
|
+@@ -5328,6 +5373,7 @@ static void __net_exit ip6_route_net_exi
|
|
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
|
kfree(net->ipv6.ip6_prohibit_entry);
|
|
kfree(net->ipv6.ip6_blk_hole_entry);
|
|
@@ -235,7 +235,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
|
#endif
|
|
dst_entries_destroy(&net->ipv6.ip6_dst_ops);
|
|
}
|
|
-@@ -5403,6 +5449,9 @@ void __init ip6_route_init_special_entri
|
|
+@@ -5404,6 +5450,9 @@ void __init ip6_route_init_special_entri
|
|
init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
|
|
init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
|
|
init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
|
|
diff --git a/target/linux/generic/pending-4.9/0931-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch b/target/linux/generic/pending-4.9/931-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch
|
|
similarity index 100%
|
|
rename from target/linux/generic/pending-4.9/0931-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch
|
|
rename to target/linux/generic/pending-4.9/931-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch
|
|
diff --git a/target/linux/ipq40xx/config-4.19 b/target/linux/ipq40xx/config-4.19
|
|
index 0de3001c8a..d01ae3cebc 100644
|
|
--- a/target/linux/ipq40xx/config-4.19
|
|
+++ b/target/linux/ipq40xx/config-4.19
|
|
@@ -47,6 +47,7 @@ CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
|
|
CONFIG_ARM_CPUIDLE=y
|
|
CONFIG_ARM_CPU_SUSPEND=y
|
|
# CONFIG_ARM_CPU_TOPOLOGY is not set
|
|
+CONFIG_ARM_CRYPTO=y
|
|
CONFIG_ARM_GIC=y
|
|
CONFIG_ARM_HAS_SG_CHAIN=y
|
|
CONFIG_ARM_L1_CACHE_SHIFT=6
|
|
@@ -115,34 +116,26 @@ CONFIG_CRC32_SLICEBY8=y
|
|
CONFIG_CRYPTO_ACOMP2=y
|
|
CONFIG_CRYPTO_AEAD=y
|
|
CONFIG_CRYPTO_AEAD2=y
|
|
-CONFIG_CRYPTO_CBC=y
|
|
-CONFIG_CRYPTO_CTR=y
|
|
+CONFIG_CRYPTO_AES_ARM=y
|
|
+CONFIG_CRYPTO_AES_ARM_BS=y
|
|
CONFIG_CRYPTO_DEFLATE=y
|
|
-CONFIG_CRYPTO_DES=y
|
|
-CONFIG_CRYPTO_DEV_QCE=y
|
|
CONFIG_CRYPTO_DEV_QCOM_RNG=y
|
|
-CONFIG_CRYPTO_DRBG=y
|
|
-CONFIG_CRYPTO_DRBG_HMAC=y
|
|
-CONFIG_CRYPTO_DRBG_MENU=y
|
|
-CONFIG_CRYPTO_ECB=y
|
|
-CONFIG_CRYPTO_GF128MUL=y
|
|
+# CONFIG_CRYPTO_GHASH_ARM_CE is not set
|
|
CONFIG_CRYPTO_HASH=y
|
|
CONFIG_CRYPTO_HASH2=y
|
|
-CONFIG_CRYPTO_HMAC=y
|
|
CONFIG_CRYPTO_HW=y
|
|
-CONFIG_CRYPTO_JITTERENTROPY=y
|
|
CONFIG_CRYPTO_LZO=y
|
|
CONFIG_CRYPTO_MANAGER=y
|
|
CONFIG_CRYPTO_MANAGER2=y
|
|
-CONFIG_CRYPTO_NULL=y
|
|
CONFIG_CRYPTO_NULL2=y
|
|
CONFIG_CRYPTO_RNG=y
|
|
CONFIG_CRYPTO_RNG2=y
|
|
-CONFIG_CRYPTO_RNG_DEFAULT=y
|
|
-CONFIG_CRYPTO_SEQIV=y
|
|
+# CONFIG_CRYPTO_SHA1_ARM_CE is not set
|
|
+# CONFIG_CRYPTO_SHA1_ARM_NEON is not set
|
|
CONFIG_CRYPTO_SHA256=y
|
|
+CONFIG_CRYPTO_SHA256_ARM=y
|
|
+CONFIG_CRYPTO_SIMD=y
|
|
CONFIG_CRYPTO_WORKQUEUE=y
|
|
-CONFIG_CRYPTO_XTS=y
|
|
CONFIG_DCACHE_WORD_ACCESS=y
|
|
CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
|
|
# CONFIG_DEBUG_USER is not set
|
|
diff --git a/target/linux/ipq40xx/patches-4.19/181-crypto-qce-add-CRYPTO_ALG_KERN_DRIVER_ONLY-flag.patch b/target/linux/ipq40xx/patches-4.19/039-crypto-qce-add-CRYPTO_ALG_KERN_DRIVER_ONLY-flag.patch
|
|
similarity index 100%
|
|
rename from target/linux/ipq40xx/patches-4.19/181-crypto-qce-add-CRYPTO_ALG_KERN_DRIVER_ONLY-flag.patch
|
|
rename to target/linux/ipq40xx/patches-4.19/039-crypto-qce-add-CRYPTO_ALG_KERN_DRIVER_ONLY-flag.patch
|
|
diff --git a/target/linux/ipq40xx/patches-4.19/040-crypto-qce-switch-to-skcipher-API.patch b/target/linux/ipq40xx/patches-4.19/040-crypto-qce-switch-to-skcipher-API.patch
|
|
new file mode 100644
|
|
index 0000000000..2adfe622e3
|
|
--- /dev/null
|
|
+++ b/target/linux/ipq40xx/patches-4.19/040-crypto-qce-switch-to-skcipher-API.patch
|
|
@@ -0,0 +1,463 @@
|
|
+From f441873642eebf20566c18d2966a8cd4b433ec1c Mon Sep 17 00:00:00 2001
|
|
+From: Ard Biesheuvel <ardb@kernel.org>
|
|
+Date: Tue, 5 Nov 2019 14:28:17 +0100
|
|
+Subject: [PATCH] crypto: qce - switch to skcipher API
|
|
+
|
|
+Commit 7a7ffe65c8c5 ("crypto: skcipher - Add top-level skcipher interface")
|
|
+dated 20 august 2015 introduced the new skcipher API which is supposed to
|
|
+replace both blkcipher and ablkcipher. While all consumers of the API have
|
|
+been converted long ago, some producers of the ablkcipher remain, forcing
|
|
+us to keep the ablkcipher support routines alive, along with the matching
|
|
+code to expose [a]blkciphers via the skcipher API.
|
|
+
|
|
+So switch this driver to the skcipher API, allowing us to finally drop the
|
|
+blkcipher code in the near future.
|
|
+
|
|
+Reviewed-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
|
|
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
|
|
+Backported-to-4.19-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+
|
|
+diff --git a/drivers/crypto/qce/Makefile b/drivers/crypto/qce/Makefile
|
|
+index 19a7f899acff..8caa04e1ec43 100644
|
|
+--- a/drivers/crypto/qce/Makefile
|
|
++++ b/drivers/crypto/qce/Makefile
|
|
+@@ -4,4 +4,4 @@ qcrypto-objs := core.o \
|
|
+ common.o \
|
|
+ dma.o \
|
|
+ sha.o \
|
|
+- ablkcipher.o
|
|
++ skcipher.o
|
|
+diff --git a/drivers/crypto/qce/cipher.h b/drivers/crypto/qce/cipher.h
|
|
+index 2b0278bb6e92..f93fab1dd1ff 100644
|
|
+--- a/drivers/crypto/qce/cipher.h
|
|
++++ b/drivers/crypto/qce/cipher.h
|
|
+@@ -53,12 +53,12 @@ struct qce_cipher_reqctx {
|
|
+ unsigned int cryptlen;
|
|
+ };
|
|
+
|
|
+-static inline struct qce_alg_template *to_cipher_tmpl(struct crypto_tfm *tfm)
|
|
++static inline struct qce_alg_template *to_cipher_tmpl(struct crypto_skcipher *tfm)
|
|
+ {
|
|
+- struct crypto_alg *alg = tfm->__crt_alg;
|
|
+- return container_of(alg, struct qce_alg_template, alg.crypto);
|
|
++ struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
|
|
++ return container_of(alg, struct qce_alg_template, alg.skcipher);
|
|
+ }
|
|
+
|
|
+-extern const struct qce_algo_ops ablkcipher_ops;
|
|
++extern const struct qce_algo_ops skcipher_ops;
|
|
+
|
|
+ #endif /* _CIPHER_H_ */
|
|
+diff --git a/drivers/crypto/qce/common.c b/drivers/crypto/qce/common.c
|
|
+index 1fb5fde7fc03..e0202755682b 100644
|
|
+--- a/drivers/crypto/qce/common.c
|
|
++++ b/drivers/crypto/qce/common.c
|
|
+@@ -312,13 +312,13 @@ static int qce_setup_regs_ahash(struct crypto_async_request *async_req,
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+-static int qce_setup_regs_ablkcipher(struct crypto_async_request *async_req,
|
|
++static int qce_setup_regs_skcipher(struct crypto_async_request *async_req,
|
|
+ u32 totallen, u32 offset)
|
|
+ {
|
|
+- struct ablkcipher_request *req = ablkcipher_request_cast(async_req);
|
|
+- struct qce_cipher_reqctx *rctx = ablkcipher_request_ctx(req);
|
|
++ struct skcipher_request *req = skcipher_request_cast(async_req);
|
|
++ struct qce_cipher_reqctx *rctx = skcipher_request_ctx(req);
|
|
+ struct qce_cipher_ctx *ctx = crypto_tfm_ctx(async_req->tfm);
|
|
+- struct qce_alg_template *tmpl = to_cipher_tmpl(async_req->tfm);
|
|
++ struct qce_alg_template *tmpl = to_cipher_tmpl(crypto_skcipher_reqtfm(req));
|
|
+ struct qce_device *qce = tmpl->qce;
|
|
+ __be32 enckey[QCE_MAX_CIPHER_KEY_SIZE / sizeof(__be32)] = {0};
|
|
+ __be32 enciv[QCE_MAX_IV_SIZE / sizeof(__be32)] = {0};
|
|
+@@ -397,8 +397,8 @@ int qce_start(struct crypto_async_request *async_req, u32 type, u32 totallen,
|
|
+ u32 offset)
|
|
+ {
|
|
+ switch (type) {
|
|
+- case CRYPTO_ALG_TYPE_ABLKCIPHER:
|
|
+- return qce_setup_regs_ablkcipher(async_req, totallen, offset);
|
|
++ case CRYPTO_ALG_TYPE_SKCIPHER:
|
|
++ return qce_setup_regs_skcipher(async_req, totallen, offset);
|
|
+ case CRYPTO_ALG_TYPE_AHASH:
|
|
+ return qce_setup_regs_ahash(async_req, totallen, offset);
|
|
+ default:
|
|
+diff --git a/drivers/crypto/qce/common.h b/drivers/crypto/qce/common.h
|
|
+index a4addd4f7d6c..3252efa41e7a 100644
|
|
+--- a/drivers/crypto/qce/common.h
|
|
++++ b/drivers/crypto/qce/common.h
|
|
+@@ -18,6 +18,7 @@
|
|
+ #include <linux/types.h>
|
|
+ #include <crypto/aes.h>
|
|
+ #include <crypto/hash.h>
|
|
++#include <crypto/internal/skcipher.h>
|
|
+
|
|
+ /* key size in bytes */
|
|
+ #define QCE_SHA_HMAC_KEY_SIZE 64
|
|
+@@ -87,7 +88,7 @@ struct qce_alg_template {
|
|
+ unsigned long alg_flags;
|
|
+ const u32 *std_iv;
|
|
+ union {
|
|
+- struct crypto_alg crypto;
|
|
++ struct skcipher_alg skcipher;
|
|
+ struct ahash_alg ahash;
|
|
+ } alg;
|
|
+ struct qce_device *qce;
|
|
+diff --git a/drivers/crypto/qce/core.c b/drivers/crypto/qce/core.c
|
|
+index 1c3b36b75467..bf409edc23ab 100644
|
|
+--- a/drivers/crypto/qce/core.c
|
|
++++ b/drivers/crypto/qce/core.c
|
|
+@@ -30,7 +30,7 @@
|
|
+ #define QCE_QUEUE_LENGTH 1
|
|
+
|
|
+ static const struct qce_algo_ops *qce_ops[] = {
|
|
+- &ablkcipher_ops,
|
|
++ &skcipher_ops,
|
|
+ &ahash_ops,
|
|
+ };
|
|
+
|
|
+diff --git a/drivers/crypto/qce/ablkcipher.c b/drivers/crypto/qce/skcipher.c
|
|
+similarity index 62%
|
|
+rename from drivers/crypto/qce/ablkcipher.c
|
|
+rename to drivers/crypto/qce/skcipher.c
|
|
+index 3658c46ef9c7..0376bb969834 100644
|
|
+--- a/drivers/crypto/qce/ablkcipher.c
|
|
++++ b/drivers/crypto/qce/skcipher.c
|
|
+@@ -20,14 +20,14 @@
|
|
+
|
|
+ #include "cipher.h"
|
|
+
|
|
+-static LIST_HEAD(ablkcipher_algs);
|
|
++static LIST_HEAD(skcipher_algs);
|
|
+
|
|
+-static void qce_ablkcipher_done(void *data)
|
|
++static void qce_skcipher_done(void *data)
|
|
+ {
|
|
+ struct crypto_async_request *async_req = data;
|
|
+- struct ablkcipher_request *req = ablkcipher_request_cast(async_req);
|
|
+- struct qce_cipher_reqctx *rctx = ablkcipher_request_ctx(req);
|
|
+- struct qce_alg_template *tmpl = to_cipher_tmpl(async_req->tfm);
|
|
++ struct skcipher_request *req = skcipher_request_cast(async_req);
|
|
++ struct qce_cipher_reqctx *rctx = skcipher_request_ctx(req);
|
|
++ struct qce_alg_template *tmpl = to_cipher_tmpl(crypto_skcipher_reqtfm(req));
|
|
+ struct qce_device *qce = tmpl->qce;
|
|
+ enum dma_data_direction dir_src, dir_dst;
|
|
+ u32 status;
|
|
+@@ -40,7 +40,7 @@ static void qce_ablkcipher_done(void *data)
|
|
+
|
|
+ error = qce_dma_terminate_all(&qce->dma);
|
|
+ if (error)
|
|
+- dev_dbg(qce->dev, "ablkcipher dma termination error (%d)\n",
|
|
++ dev_dbg(qce->dev, "skcipher dma termination error (%d)\n",
|
|
+ error);
|
|
+
|
|
+ if (diff_dst)
|
|
+@@ -51,18 +51,18 @@ static void qce_ablkcipher_done(void *data)
|
|
+
|
|
+ error = qce_check_status(qce, &status);
|
|
+ if (error < 0)
|
|
+- dev_dbg(qce->dev, "ablkcipher operation error (%x)\n", status);
|
|
++ dev_dbg(qce->dev, "skcipher operation error (%x)\n", status);
|
|
+
|
|
+ qce->async_req_done(tmpl->qce, error);
|
|
+ }
|
|
+
|
|
+ static int
|
|
+-qce_ablkcipher_async_req_handle(struct crypto_async_request *async_req)
|
|
++qce_skcipher_async_req_handle(struct crypto_async_request *async_req)
|
|
+ {
|
|
+- struct ablkcipher_request *req = ablkcipher_request_cast(async_req);
|
|
+- struct qce_cipher_reqctx *rctx = ablkcipher_request_ctx(req);
|
|
+- struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
|
|
+- struct qce_alg_template *tmpl = to_cipher_tmpl(async_req->tfm);
|
|
++ struct skcipher_request *req = skcipher_request_cast(async_req);
|
|
++ struct qce_cipher_reqctx *rctx = skcipher_request_ctx(req);
|
|
++ struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
|
|
++ struct qce_alg_template *tmpl = to_cipher_tmpl(crypto_skcipher_reqtfm(req));
|
|
+ struct qce_device *qce = tmpl->qce;
|
|
+ enum dma_data_direction dir_src, dir_dst;
|
|
+ struct scatterlist *sg;
|
|
+@@ -70,17 +70,17 @@ qce_ablkcipher_async_req_handle(struct crypto_async_request *async_req)
|
|
+ gfp_t gfp;
|
|
+ int ret;
|
|
+
|
|
+- rctx->iv = req->info;
|
|
+- rctx->ivsize = crypto_ablkcipher_ivsize(ablkcipher);
|
|
+- rctx->cryptlen = req->nbytes;
|
|
++ rctx->iv = req->iv;
|
|
++ rctx->ivsize = crypto_skcipher_ivsize(skcipher);
|
|
++ rctx->cryptlen = req->cryptlen;
|
|
+
|
|
+ diff_dst = (req->src != req->dst) ? true : false;
|
|
+ dir_src = diff_dst ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL;
|
|
+ dir_dst = diff_dst ? DMA_FROM_DEVICE : DMA_BIDIRECTIONAL;
|
|
+
|
|
+- rctx->src_nents = sg_nents_for_len(req->src, req->nbytes);
|
|
++ rctx->src_nents = sg_nents_for_len(req->src, req->cryptlen);
|
|
+ if (diff_dst)
|
|
+- rctx->dst_nents = sg_nents_for_len(req->dst, req->nbytes);
|
|
++ rctx->dst_nents = sg_nents_for_len(req->dst, req->cryptlen);
|
|
+ else
|
|
+ rctx->dst_nents = rctx->src_nents;
|
|
+ if (rctx->src_nents < 0) {
|
|
+@@ -133,13 +133,13 @@ qce_ablkcipher_async_req_handle(struct crypto_async_request *async_req)
|
|
+
|
|
+ ret = qce_dma_prep_sgs(&qce->dma, rctx->src_sg, rctx->src_nents,
|
|
+ rctx->dst_sg, rctx->dst_nents,
|
|
+- qce_ablkcipher_done, async_req);
|
|
++ qce_skcipher_done, async_req);
|
|
+ if (ret)
|
|
+ goto error_unmap_src;
|
|
+
|
|
+ qce_dma_issue_pending(&qce->dma);
|
|
+
|
|
+- ret = qce_start(async_req, tmpl->crypto_alg_type, req->nbytes, 0);
|
|
++ ret = qce_start(async_req, tmpl->crypto_alg_type, req->cryptlen, 0);
|
|
+ if (ret)
|
|
+ goto error_terminate;
|
|
+
|
|
+@@ -157,12 +157,11 @@ qce_ablkcipher_async_req_handle(struct crypto_async_request *async_req)
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+-static int qce_ablkcipher_setkey(struct crypto_ablkcipher *ablk, const u8 *key,
|
|
++static int qce_skcipher_setkey(struct crypto_skcipher *ablk, const u8 *key,
|
|
+ unsigned int keylen)
|
|
+ {
|
|
+- struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ablk);
|
|
+- struct qce_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
|
|
+- unsigned long flags = to_cipher_tmpl(tfm)->alg_flags;
|
|
++ struct qce_cipher_ctx *ctx = crypto_skcipher_ctx(ablk);
|
|
++ unsigned long flags = to_cipher_tmpl(ablk)->alg_flags;
|
|
+ int ret;
|
|
+
|
|
+ if (!key || !keylen)
|
|
+@@ -180,7 +179,7 @@ static int qce_ablkcipher_setkey(struct crypto_ablkcipher *ablk, const u8 *key,
|
|
+ u32 tmp[DES_EXPKEY_WORDS];
|
|
+
|
|
+ ret = des_ekey(tmp, key);
|
|
+- if (!ret && crypto_ablkcipher_get_flags(ablk) &
|
|
++ if (!ret && crypto_skcipher_get_flags(ablk) &
|
|
+ CRYPTO_TFM_REQ_WEAK_KEY)
|
|
+ goto weakkey;
|
|
+ }
|
|
+@@ -194,16 +193,15 @@ static int qce_ablkcipher_setkey(struct crypto_ablkcipher *ablk, const u8 *key,
|
|
+ ctx->enc_keylen = keylen;
|
|
+ return ret;
|
|
+ weakkey:
|
|
+- crypto_ablkcipher_set_flags(ablk, CRYPTO_TFM_RES_WEAK_KEY);
|
|
++ crypto_skcipher_set_flags(ablk, CRYPTO_TFM_RES_WEAK_KEY);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+-static int qce_ablkcipher_crypt(struct ablkcipher_request *req, int encrypt)
|
|
++static int qce_skcipher_crypt(struct skcipher_request *req, int encrypt)
|
|
+ {
|
|
+- struct crypto_tfm *tfm =
|
|
+- crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req));
|
|
+- struct qce_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
|
|
+- struct qce_cipher_reqctx *rctx = ablkcipher_request_ctx(req);
|
|
++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
|
++ struct qce_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
|
|
++ struct qce_cipher_reqctx *rctx = skcipher_request_ctx(req);
|
|
+ struct qce_alg_template *tmpl = to_cipher_tmpl(tfm);
|
|
+ int ret;
|
|
+
|
|
+@@ -218,7 +216,7 @@ static int qce_ablkcipher_crypt(struct ablkcipher_request *req, int encrypt)
|
|
+ skcipher_request_set_callback(subreq, req->base.flags,
|
|
+ NULL, NULL);
|
|
+ skcipher_request_set_crypt(subreq, req->src, req->dst,
|
|
+- req->nbytes, req->info);
|
|
++ req->cryptlen, req->iv);
|
|
+ ret = encrypt ? crypto_skcipher_encrypt(subreq) :
|
|
+ crypto_skcipher_decrypt(subreq);
|
|
+ skcipher_request_zero(subreq);
|
|
+@@ -228,37 +226,37 @@ static int qce_ablkcipher_crypt(struct ablkcipher_request *req, int encrypt)
|
|
+ return tmpl->qce->async_req_enqueue(tmpl->qce, &req->base);
|
|
+ }
|
|
+
|
|
+-static int qce_ablkcipher_encrypt(struct ablkcipher_request *req)
|
|
++static int qce_skcipher_encrypt(struct skcipher_request *req)
|
|
+ {
|
|
+- return qce_ablkcipher_crypt(req, 1);
|
|
++ return qce_skcipher_crypt(req, 1);
|
|
+ }
|
|
+
|
|
+-static int qce_ablkcipher_decrypt(struct ablkcipher_request *req)
|
|
++static int qce_skcipher_decrypt(struct skcipher_request *req)
|
|
+ {
|
|
+- return qce_ablkcipher_crypt(req, 0);
|
|
++ return qce_skcipher_crypt(req, 0);
|
|
+ }
|
|
+
|
|
+-static int qce_ablkcipher_init(struct crypto_tfm *tfm)
|
|
++static int qce_skcipher_init(struct crypto_skcipher *tfm)
|
|
+ {
|
|
+- struct qce_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
|
|
++ struct qce_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
|
|
+
|
|
+ memset(ctx, 0, sizeof(*ctx));
|
|
+- tfm->crt_ablkcipher.reqsize = sizeof(struct qce_cipher_reqctx);
|
|
++ crypto_skcipher_set_reqsize(tfm, sizeof(struct qce_cipher_reqctx));
|
|
+
|
|
+- ctx->fallback = crypto_alloc_skcipher(crypto_tfm_alg_name(tfm), 0,
|
|
+- CRYPTO_ALG_ASYNC |
|
|
+- CRYPTO_ALG_NEED_FALLBACK);
|
|
++ ctx->fallback = crypto_alloc_skcipher(crypto_tfm_alg_name(&tfm->base),
|
|
++ 0, CRYPTO_ALG_ASYNC |
|
|
++ CRYPTO_ALG_NEED_FALLBACK);
|
|
+ return PTR_ERR_OR_ZERO(ctx->fallback);
|
|
+ }
|
|
+
|
|
+-static void qce_ablkcipher_exit(struct crypto_tfm *tfm)
|
|
++static void qce_skcipher_exit(struct crypto_skcipher *tfm)
|
|
+ {
|
|
+- struct qce_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
|
|
++ struct qce_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
|
|
+
|
|
+ crypto_free_skcipher(ctx->fallback);
|
|
+ }
|
|
+
|
|
+-struct qce_ablkcipher_def {
|
|
++struct qce_skcipher_def {
|
|
+ unsigned long flags;
|
|
+ const char *name;
|
|
+ const char *drv_name;
|
|
+@@ -268,7 +266,7 @@ struct qce_ablkcipher_def {
|
|
+ unsigned int max_keysize;
|
|
+ };
|
|
+
|
|
+-static const struct qce_ablkcipher_def ablkcipher_def[] = {
|
|
++static const struct qce_skcipher_def skcipher_def[] = {
|
|
+ {
|
|
+ .flags = QCE_ALG_AES | QCE_MODE_ECB,
|
|
+ .name = "ecb(aes)",
|
|
+@@ -343,89 +341,89 @@ static const struct qce_ablkcipher_def ablkcipher_def[] = {
|
|
+ },
|
|
+ };
|
|
+
|
|
+-static int qce_ablkcipher_register_one(const struct qce_ablkcipher_def *def,
|
|
++static int qce_skcipher_register_one(const struct qce_skcipher_def *def,
|
|
+ struct qce_device *qce)
|
|
+ {
|
|
+ struct qce_alg_template *tmpl;
|
|
+- struct crypto_alg *alg;
|
|
++ struct skcipher_alg *alg;
|
|
+ int ret;
|
|
+
|
|
+ tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL);
|
|
+ if (!tmpl)
|
|
+ return -ENOMEM;
|
|
+
|
|
+- alg = &tmpl->alg.crypto;
|
|
++ alg = &tmpl->alg.skcipher;
|
|
+
|
|
+- snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", def->name);
|
|
+- snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
|
|
++ snprintf(alg->base.cra_name, CRYPTO_MAX_ALG_NAME, "%s", def->name);
|
|
++ snprintf(alg->base.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
|
|
+ def->drv_name);
|
|
+
|
|
+- alg->cra_blocksize = def->blocksize;
|
|
+- alg->cra_ablkcipher.ivsize = def->ivsize;
|
|
+- alg->cra_ablkcipher.min_keysize = def->min_keysize;
|
|
+- alg->cra_ablkcipher.max_keysize = def->max_keysize;
|
|
+- alg->cra_ablkcipher.setkey = qce_ablkcipher_setkey;
|
|
+- alg->cra_ablkcipher.encrypt = qce_ablkcipher_encrypt;
|
|
+- alg->cra_ablkcipher.decrypt = qce_ablkcipher_decrypt;
|
|
+-
|
|
+- alg->cra_priority = 300;
|
|
+- alg->cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC |
|
|
+- CRYPTO_ALG_NEED_FALLBACK | CRYPTO_ALG_KERN_DRIVER_ONLY;
|
|
+- alg->cra_ctxsize = sizeof(struct qce_cipher_ctx);
|
|
+- alg->cra_alignmask = 0;
|
|
+- alg->cra_type = &crypto_ablkcipher_type;
|
|
+- alg->cra_module = THIS_MODULE;
|
|
+- alg->cra_init = qce_ablkcipher_init;
|
|
+- alg->cra_exit = qce_ablkcipher_exit;
|
|
+- INIT_LIST_HEAD(&alg->cra_list);
|
|
++ alg->base.cra_blocksize = def->blocksize;
|
|
++ alg->ivsize = def->ivsize;
|
|
++ alg->min_keysize = def->min_keysize;
|
|
++ alg->max_keysize = def->max_keysize;
|
|
++ alg->setkey = qce_skcipher_setkey;
|
|
++ alg->encrypt = qce_skcipher_encrypt;
|
|
++ alg->decrypt = qce_skcipher_decrypt;
|
|
++
|
|
++ alg->base.cra_priority = 300;
|
|
++ alg->base.cra_flags = CRYPTO_ALG_ASYNC |
|
|
++ CRYPTO_ALG_NEED_FALLBACK |
|
|
++ CRYPTO_ALG_KERN_DRIVER_ONLY;
|
|
++ alg->base.cra_ctxsize = sizeof(struct qce_cipher_ctx);
|
|
++ alg->base.cra_alignmask = 0;
|
|
++ alg->base.cra_module = THIS_MODULE;
|
|
++
|
|
++ alg->init = qce_skcipher_init;
|
|
++ alg->exit = qce_skcipher_exit;
|
|
+
|
|
+ INIT_LIST_HEAD(&tmpl->entry);
|
|
+- tmpl->crypto_alg_type = CRYPTO_ALG_TYPE_ABLKCIPHER;
|
|
++ tmpl->crypto_alg_type = CRYPTO_ALG_TYPE_SKCIPHER;
|
|
+ tmpl->alg_flags = def->flags;
|
|
+ tmpl->qce = qce;
|
|
+
|
|
+- ret = crypto_register_alg(alg);
|
|
++ ret = crypto_register_skcipher(alg);
|
|
+ if (ret) {
|
|
+ kfree(tmpl);
|
|
+- dev_err(qce->dev, "%s registration failed\n", alg->cra_name);
|
|
++ dev_err(qce->dev, "%s registration failed\n", alg->base.cra_name);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+- list_add_tail(&tmpl->entry, &ablkcipher_algs);
|
|
+- dev_dbg(qce->dev, "%s is registered\n", alg->cra_name);
|
|
++ list_add_tail(&tmpl->entry, &skcipher_algs);
|
|
++ dev_dbg(qce->dev, "%s is registered\n", alg->base.cra_name);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+-static void qce_ablkcipher_unregister(struct qce_device *qce)
|
|
++static void qce_skcipher_unregister(struct qce_device *qce)
|
|
+ {
|
|
+ struct qce_alg_template *tmpl, *n;
|
|
+
|
|
+- list_for_each_entry_safe(tmpl, n, &ablkcipher_algs, entry) {
|
|
+- crypto_unregister_alg(&tmpl->alg.crypto);
|
|
++ list_for_each_entry_safe(tmpl, n, &skcipher_algs, entry) {
|
|
++ crypto_unregister_skcipher(&tmpl->alg.skcipher);
|
|
+ list_del(&tmpl->entry);
|
|
+ kfree(tmpl);
|
|
+ }
|
|
+ }
|
|
+
|
|
+-static int qce_ablkcipher_register(struct qce_device *qce)
|
|
++static int qce_skcipher_register(struct qce_device *qce)
|
|
+ {
|
|
+ int ret, i;
|
|
+
|
|
+- for (i = 0; i < ARRAY_SIZE(ablkcipher_def); i++) {
|
|
+- ret = qce_ablkcipher_register_one(&ablkcipher_def[i], qce);
|
|
++ for (i = 0; i < ARRAY_SIZE(skcipher_def); i++) {
|
|
++ ret = qce_skcipher_register_one(&skcipher_def[i], qce);
|
|
+ if (ret)
|
|
+ goto err;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+ err:
|
|
+- qce_ablkcipher_unregister(qce);
|
|
++ qce_skcipher_unregister(qce);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+-const struct qce_algo_ops ablkcipher_ops = {
|
|
+- .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
|
|
+- .register_algs = qce_ablkcipher_register,
|
|
+- .unregister_algs = qce_ablkcipher_unregister,
|
|
+- .async_req_handle = qce_ablkcipher_async_req_handle,
|
|
++const struct qce_algo_ops skcipher_ops = {
|
|
++ .type = CRYPTO_ALG_TYPE_SKCIPHER,
|
|
++ .register_algs = qce_skcipher_register,
|
|
++ .unregister_algs = qce_skcipher_unregister,
|
|
++ .async_req_handle = qce_skcipher_async_req_handle,
|
|
+ };
|
|
diff --git a/target/linux/ipq40xx/patches-4.19/041-crypto-qce-fix-ctr-aes-qce-block-chunk-sizes.patch b/target/linux/ipq40xx/patches-4.19/041-crypto-qce-fix-ctr-aes-qce-block-chunk-sizes.patch
|
|
new file mode 100644
|
|
index 0000000000..7d822c59d6
|
|
--- /dev/null
|
|
+++ b/target/linux/ipq40xx/patches-4.19/041-crypto-qce-fix-ctr-aes-qce-block-chunk-sizes.patch
|
|
@@ -0,0 +1,41 @@
|
|
+From 3f5598286445f695bb63a22239dd3603c69a6eaf Mon Sep 17 00:00:00 2001
|
|
+From: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+Date: Mon, 28 Oct 2019 09:03:07 -0300
|
|
+Subject: [PATCH] crypto: qce - fix ctr-aes-qce block, chunk sizes
|
|
+
|
|
+Set blocksize of ctr-aes-qce to 1, so it can operate as a stream cipher,
|
|
+adding the definition for chucksize instead, where the underlying block
|
|
+size belongs.
|
|
+
|
|
+Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+
|
|
+diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c
|
|
+index 0376bb969834..0776286cfc9e 100644
|
|
+--- a/drivers/crypto/qce/skcipher.c
|
|
++++ b/drivers/crypto/qce/skcipher.c
|
|
+@@ -261,6 +261,7 @@ struct qce_skcipher_def {
|
|
+ const char *name;
|
|
+ const char *drv_name;
|
|
+ unsigned int blocksize;
|
|
++ unsigned int chunksize;
|
|
+ unsigned int ivsize;
|
|
+ unsigned int min_keysize;
|
|
+ unsigned int max_keysize;
|
|
+@@ -289,7 +290,8 @@ static const struct qce_skcipher_def skcipher_def[] = {
|
|
+ .flags = QCE_ALG_AES | QCE_MODE_CTR,
|
|
+ .name = "ctr(aes)",
|
|
+ .drv_name = "ctr-aes-qce",
|
|
+- .blocksize = AES_BLOCK_SIZE,
|
|
++ .blocksize = 1,
|
|
++ .chunksize = AES_BLOCK_SIZE,
|
|
+ .ivsize = AES_BLOCK_SIZE,
|
|
+ .min_keysize = AES_MIN_KEY_SIZE,
|
|
+ .max_keysize = AES_MAX_KEY_SIZE,
|
|
+@@ -359,6 +361,7 @@ static int qce_skcipher_register_one(const struct qce_skcipher_def *def,
|
|
+ def->drv_name);
|
|
+
|
|
+ alg->base.cra_blocksize = def->blocksize;
|
|
++ alg->chunksize = def->chunksize;
|
|
+ alg->ivsize = def->ivsize;
|
|
+ alg->min_keysize = def->min_keysize;
|
|
+ alg->max_keysize = def->max_keysize;
|
|
diff --git a/target/linux/ipq40xx/patches-4.19/042-crypto-qce-fix-xts-aes-qce-key-sizes.patch b/target/linux/ipq40xx/patches-4.19/042-crypto-qce-fix-xts-aes-qce-key-sizes.patch
|
|
new file mode 100644
|
|
index 0000000000..dd58dcd801
|
|
--- /dev/null
|
|
+++ b/target/linux/ipq40xx/patches-4.19/042-crypto-qce-fix-xts-aes-qce-key-sizes.patch
|
|
@@ -0,0 +1,52 @@
|
|
+From 0138c3c13809250338d7cfba6f4ca3b2da02b2c8 Mon Sep 17 00:00:00 2001
|
|
+From: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+Date: Thu, 21 Nov 2019 14:28:23 -0300
|
|
+Subject: [PATCH] crypto: qce - fix xts-aes-qce key sizes
|
|
+
|
|
+XTS-mode uses two keys, so the keysizes should be doubled in
|
|
+skcipher_def, and halved when checking if it is AES-128/192/256.
|
|
+
|
|
+Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+
|
|
+diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c
|
|
+index 0776286cfc9e..9b1bb32515b4 100644
|
|
+--- a/drivers/crypto/qce/skcipher.c
|
|
++++ b/drivers/crypto/qce/skcipher.c
|
|
+@@ -168,7 +168,7 @@ static int qce_skcipher_setkey(struct crypto_skcipher *ablk, const u8 *key,
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (IS_AES(flags)) {
|
|
+- switch (keylen) {
|
|
++ switch (IS_XTS(flags) ? keylen >> 1 : keylen) {
|
|
+ case AES_KEYSIZE_128:
|
|
+ case AES_KEYSIZE_256:
|
|
+ break;
|
|
+@@ -203,13 +203,15 @@ static int qce_skcipher_crypt(struct skcipher_request *req, int encrypt)
|
|
+ struct qce_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
|
|
+ struct qce_cipher_reqctx *rctx = skcipher_request_ctx(req);
|
|
+ struct qce_alg_template *tmpl = to_cipher_tmpl(tfm);
|
|
++ int keylen;
|
|
+ int ret;
|
|
+
|
|
+ rctx->flags = tmpl->alg_flags;
|
|
+ rctx->flags |= encrypt ? QCE_ENCRYPT : QCE_DECRYPT;
|
|
++ keylen = IS_XTS(rctx->flags) ? ctx->enc_keylen >> 1 : ctx->enc_keylen;
|
|
+
|
|
+- if (IS_AES(rctx->flags) && ctx->enc_keylen != AES_KEYSIZE_128 &&
|
|
+- ctx->enc_keylen != AES_KEYSIZE_256) {
|
|
++ if (IS_AES(rctx->flags) && keylen != AES_KEYSIZE_128 &&
|
|
++ keylen != AES_KEYSIZE_256) {
|
|
+ SKCIPHER_REQUEST_ON_STACK(subreq, ctx->fallback);
|
|
+
|
|
+ skcipher_request_set_tfm(subreq, ctx->fallback);
|
|
+@@ -302,8 +304,8 @@ static const struct qce_skcipher_def skcipher_def[] = {
|
|
+ .drv_name = "xts-aes-qce",
|
|
+ .blocksize = AES_BLOCK_SIZE,
|
|
+ .ivsize = AES_BLOCK_SIZE,
|
|
+- .min_keysize = AES_MIN_KEY_SIZE,
|
|
+- .max_keysize = AES_MAX_KEY_SIZE,
|
|
++ .min_keysize = AES_MIN_KEY_SIZE * 2,
|
|
++ .max_keysize = AES_MAX_KEY_SIZE * 2,
|
|
+ },
|
|
+ {
|
|
+ .flags = QCE_ALG_DES | QCE_MODE_ECB,
|
|
diff --git a/target/linux/ipq40xx/patches-4.19/043-crypto-qce-save-a-sg-table-slot-for-result-buf.patch b/target/linux/ipq40xx/patches-4.19/043-crypto-qce-save-a-sg-table-slot-for-result-buf.patch
|
|
new file mode 100644
|
|
index 0000000000..9f107db035
|
|
--- /dev/null
|
|
+++ b/target/linux/ipq40xx/patches-4.19/043-crypto-qce-save-a-sg-table-slot-for-result-buf.patch
|
|
@@ -0,0 +1,85 @@
|
|
+From 31f796293b6c38126a466414c565827b9cfdbe39 Mon Sep 17 00:00:00 2001
|
|
+From: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+Date: Wed, 20 Nov 2019 21:39:11 -0300
|
|
+Subject: [PATCH] crypto: qce - save a sg table slot for result buf
|
|
+
|
|
+When ctr-aes-qce is used for gcm-mode, an extra sg entry for the
|
|
+authentication tag is present, causing trouble when the qce driver
|
|
+prepares the dst-results eg table for dma.
|
|
+
|
|
+It computes the number of entries needed with sg_nents_for_len, leaving
|
|
+out the tag entry. Then it creates a sg table with that number plus
|
|
+one, used to store a "result" sg.
|
|
+
|
|
+When copying the sg table, it does not limit the number of entries
|
|
+copied, so tha extra slot is filled with the authentication tag sg.
|
|
+When the driver tries to add the result sg, the list is full, and it
|
|
+returns EINVAL.
|
|
+
|
|
+By limiting the number of sg entries copied to the dest table, the slot
|
|
+for the result buffer is guaranteed to be unused.
|
|
+
|
|
+Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+
|
|
+diff --git a/drivers/crypto/qce/dma.c b/drivers/crypto/qce/dma.c
|
|
+index 4797e795c9b9..db560c3d3e4f 100644
|
|
+--- a/drivers/crypto/qce/dma.c
|
|
++++ b/drivers/crypto/qce/dma.c
|
|
+@@ -55,7 +55,8 @@ void qce_dma_release(struct qce_dma_data *dma)
|
|
+ }
|
|
+
|
|
+ struct scatterlist *
|
|
+-qce_sgtable_add(struct sg_table *sgt, struct scatterlist *new_sgl)
|
|
++qce_sgtable_add(struct sg_table *sgt, struct scatterlist *new_sgl,
|
|
++ int max_ents)
|
|
+ {
|
|
+ struct scatterlist *sg = sgt->sgl, *sg_last = NULL;
|
|
+
|
|
+@@ -68,12 +69,13 @@ qce_sgtable_add(struct sg_table *sgt, struct scatterlist *new_sgl)
|
|
+ if (!sg)
|
|
+ return ERR_PTR(-EINVAL);
|
|
+
|
|
+- while (new_sgl && sg) {
|
|
++ while (new_sgl && sg && max_ents) {
|
|
+ sg_set_page(sg, sg_page(new_sgl), new_sgl->length,
|
|
+ new_sgl->offset);
|
|
+ sg_last = sg;
|
|
+ sg = sg_next(sg);
|
|
+ new_sgl = sg_next(new_sgl);
|
|
++ max_ents--;
|
|
+ }
|
|
+
|
|
+ return sg_last;
|
|
+diff --git a/drivers/crypto/qce/dma.h b/drivers/crypto/qce/dma.h
|
|
+index 130235d17bb4..0be71f7f7a58 100644
|
|
+--- a/drivers/crypto/qce/dma.h
|
|
++++ b/drivers/crypto/qce/dma.h
|
|
+@@ -50,6 +50,7 @@ int qce_dma_prep_sgs(struct qce_dma_data *dma, struct scatterlist *sg_in,
|
|
+ void qce_dma_issue_pending(struct qce_dma_data *dma);
|
|
+ int qce_dma_terminate_all(struct qce_dma_data *dma);
|
|
+ struct scatterlist *
|
|
+-qce_sgtable_add(struct sg_table *sgt, struct scatterlist *sg_add);
|
|
++qce_sgtable_add(struct sg_table *sgt, struct scatterlist *sg_add,
|
|
++ int max_ents);
|
|
+
|
|
+ #endif /* _DMA_H_ */
|
|
+diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c
|
|
+index 12f882032544..33d998f5cf5f 100644
|
|
+--- a/drivers/crypto/qce/skcipher.c
|
|
++++ b/drivers/crypto/qce/skcipher.c
|
|
+@@ -103,13 +103,13 @@ qce_skcipher_async_req_handle(struct crypto_async_request *async_req)
|
|
+
|
|
+ sg_init_one(&rctx->result_sg, qce->dma.result_buf, QCE_RESULT_BUF_SZ);
|
|
+
|
|
+- sg = qce_sgtable_add(&rctx->dst_tbl, req->dst);
|
|
++ sg = qce_sgtable_add(&rctx->dst_tbl, req->dst, rctx->dst_nents - 1);
|
|
+ if (IS_ERR(sg)) {
|
|
+ ret = PTR_ERR(sg);
|
|
+ goto error_free;
|
|
+ }
|
|
+
|
|
+- sg = qce_sgtable_add(&rctx->dst_tbl, &rctx->result_sg);
|
|
++ sg = qce_sgtable_add(&rctx->dst_tbl, &rctx->result_sg, 1);
|
|
+ if (IS_ERR(sg)) {
|
|
+ ret = PTR_ERR(sg);
|
|
+ goto error_free;
|
|
diff --git a/target/linux/ipq40xx/patches-4.19/044-crypto-qce-update-the-skcipher-IV.patch b/target/linux/ipq40xx/patches-4.19/044-crypto-qce-update-the-skcipher-IV.patch
|
|
new file mode 100644
|
|
index 0000000000..de7829e767
|
|
--- /dev/null
|
|
+++ b/target/linux/ipq40xx/patches-4.19/044-crypto-qce-update-the-skcipher-IV.patch
|
|
@@ -0,0 +1,29 @@
|
|
+From 502ca0b7c1d856a46dbd78e67690c12c47775b97 Mon Sep 17 00:00:00 2001
|
|
+From: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+Date: Fri, 22 Nov 2019 09:00:02 -0300
|
|
+Subject: [PATCH] crypto: qce - update the skcipher IV
|
|
+
|
|
+Update the IV after the completion of each cipher operation.
|
|
+
|
|
+Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+
|
|
+diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c
|
|
+index 33d998f5cf5f..51377395ed53 100644
|
|
+--- a/drivers/crypto/qce/skcipher.c
|
|
++++ b/drivers/crypto/qce/skcipher.c
|
|
+@@ -29,6 +29,7 @@ static void qce_skcipher_done(void *data)
|
|
+ struct qce_cipher_reqctx *rctx = skcipher_request_ctx(req);
|
|
+ struct qce_alg_template *tmpl = to_cipher_tmpl(crypto_skcipher_reqtfm(req));
|
|
+ struct qce_device *qce = tmpl->qce;
|
|
++ struct qce_result_dump *result_buf = qce->dma.result_buf;
|
|
+ enum dma_data_direction dir_src, dir_dst;
|
|
+ u32 status;
|
|
+ int error;
|
|
+@@ -53,6 +54,7 @@ static void qce_skcipher_done(void *data)
|
|
+ if (error < 0)
|
|
+ dev_dbg(qce->dev, "skcipher operation error (%x)\n", status);
|
|
+
|
|
++ memcpy(rctx->iv, result_buf->encr_cntr_iv, rctx->ivsize);
|
|
+ qce->async_req_done(tmpl->qce, error);
|
|
+ }
|
|
+
|
|
diff --git a/target/linux/ipq40xx/patches-4.19/046-crypto-qce-initialize-fallback-only-for-AES.patch b/target/linux/ipq40xx/patches-4.19/046-crypto-qce-initialize-fallback-only-for-AES.patch
|
|
new file mode 100644
|
|
index 0000000000..b673884ba2
|
|
--- /dev/null
|
|
+++ b/target/linux/ipq40xx/patches-4.19/046-crypto-qce-initialize-fallback-only-for-AES.patch
|
|
@@ -0,0 +1,56 @@
|
|
+From f2a33ce18232919d3831d1c61a06b6067209282d Mon Sep 17 00:00:00 2001
|
|
+From: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+Date: Fri, 22 Nov 2019 09:34:29 -0300
|
|
+Subject: [PATCH] crypto: qce - initialize fallback only for AES
|
|
+
|
|
+Adjust cra_flags to add CRYPTO_NEED_FALLBACK only for AES ciphers, where
|
|
+AES-192 is not handled by the qce hardware, and don't allocate & free
|
|
+the fallback skcipher for anything other than AES.
|
|
+
|
|
+The rest of the code is unchanged, as the use of the fallback is already
|
|
+restricted to AES.
|
|
+
|
|
+Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+
|
|
+diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c
|
|
+index 51377395ed53..5a4863091f2a 100644
|
|
+--- a/drivers/crypto/qce/skcipher.c
|
|
++++ b/drivers/crypto/qce/skcipher.c
|
|
+@@ -246,7 +246,15 @@ static int qce_skcipher_init(struct crypto_skcipher *tfm)
|
|
+
|
|
+ memset(ctx, 0, sizeof(*ctx));
|
|
+ crypto_skcipher_set_reqsize(tfm, sizeof(struct qce_cipher_reqctx));
|
|
++ return 0;
|
|
++}
|
|
++
|
|
++static int qce_skcipher_init_fallback(struct crypto_skcipher *tfm)
|
|
++{
|
|
++ struct qce_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
|
|
++ int ret;
|
|
+
|
|
++ qce_skcipher_init(tfm);
|
|
+ ctx->fallback = crypto_alloc_skcipher(crypto_tfm_alg_name(&tfm->base),
|
|
+ 0, CRYPTO_ALG_ASYNC |
|
|
+ CRYPTO_ALG_NEED_FALLBACK);
|
|
+@@ -375,14 +383,18 @@ static int qce_skcipher_register_one(const struct qce_skcipher_def *def,
|
|
+
|
|
+ alg->base.cra_priority = 300;
|
|
+ alg->base.cra_flags = CRYPTO_ALG_ASYNC |
|
|
+- CRYPTO_ALG_NEED_FALLBACK |
|
|
+ CRYPTO_ALG_KERN_DRIVER_ONLY;
|
|
+ alg->base.cra_ctxsize = sizeof(struct qce_cipher_ctx);
|
|
+ alg->base.cra_alignmask = 0;
|
|
+ alg->base.cra_module = THIS_MODULE;
|
|
+
|
|
+- alg->init = qce_skcipher_init;
|
|
+- alg->exit = qce_skcipher_exit;
|
|
++ if (IS_AES(def->flags)) {
|
|
++ alg->base.cra_flags |= CRYPTO_ALG_NEED_FALLBACK;
|
|
++ alg->init = qce_skcipher_init_fallback;
|
|
++ alg->exit = qce_skcipher_exit;
|
|
++ } else {
|
|
++ alg->init = qce_skcipher_init;
|
|
++ }
|
|
+
|
|
+ INIT_LIST_HEAD(&tmpl->entry);
|
|
+ tmpl->crypto_alg_type = CRYPTO_ALG_TYPE_SKCIPHER;
|
|
diff --git a/target/linux/ipq40xx/patches-4.19/047-crypto-qce-use-cryptlen-when-adding-extra-sgl.patch b/target/linux/ipq40xx/patches-4.19/047-crypto-qce-use-cryptlen-when-adding-extra-sgl.patch
|
|
new file mode 100644
|
|
index 0000000000..8003f7502a
|
|
--- /dev/null
|
|
+++ b/target/linux/ipq40xx/patches-4.19/047-crypto-qce-use-cryptlen-when-adding-extra-sgl.patch
|
|
@@ -0,0 +1,89 @@
|
|
+From 686aa4db696270dadc5e8b2971769e1676251ff1 Mon Sep 17 00:00:00 2001
|
|
+From: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+Date: Fri, 31 Jan 2020 17:43:16 -0300
|
|
+Subject: [PATCH] crypto: qce - use cryptlen when adding extra sgl
|
|
+
|
|
+The qce crypto driver appends an extra entry to the dst sgl, to maintain
|
|
+private state information.
|
|
+
|
|
+When the gcm driver sends requests to the ctr skcipher, it passes the
|
|
+authentication tag after the actual crypto payload, but it must not be
|
|
+touched.
|
|
+
|
|
+Commit 1336c2221bee ("crypto: qce - save a sg table slot for result
|
|
+buf") limited the destination sgl to avoid overwriting the
|
|
+authentication tag but it assumed the tag would be in a separate sgl
|
|
+entry.
|
|
+
|
|
+This is not always the case, so it is better to limit the length of the
|
|
+destination buffer to req->cryptlen before appending the result buf.
|
|
+
|
|
+Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+
|
|
+diff --git a/drivers/crypto/qce/dma.c b/drivers/crypto/qce/dma.c
|
|
+index db560c3d3e4f..0ae9d28afa69 100644
|
|
+--- a/drivers/crypto/qce/dma.c
|
|
++++ b/drivers/crypto/qce/dma.c
|
|
+@@ -56,9 +56,10 @@ void qce_dma_release(struct qce_dma_data *dma)
|
|
+
|
|
+ struct scatterlist *
|
|
+ qce_sgtable_add(struct sg_table *sgt, struct scatterlist *new_sgl,
|
|
+- int max_ents)
|
|
++ unsigned int max_len)
|
|
+ {
|
|
+ struct scatterlist *sg = sgt->sgl, *sg_last = NULL;
|
|
++ unsigned int new_len;
|
|
+
|
|
+ while (sg) {
|
|
+ if (!sg_page(sg))
|
|
+@@ -69,13 +70,13 @@ qce_sgtable_add(struct sg_table *sgt, struct scatterlist *new_sgl,
|
|
+ if (!sg)
|
|
+ return ERR_PTR(-EINVAL);
|
|
+
|
|
+- while (new_sgl && sg && max_ents) {
|
|
+- sg_set_page(sg, sg_page(new_sgl), new_sgl->length,
|
|
+- new_sgl->offset);
|
|
++ while (new_sgl && sg && max_len) {
|
|
++ new_len = new_sgl->length > max_len ? max_len : new_sgl->length;
|
|
++ sg_set_page(sg, sg_page(new_sgl), new_len, new_sgl->offset);
|
|
+ sg_last = sg;
|
|
+ sg = sg_next(sg);
|
|
+ new_sgl = sg_next(new_sgl);
|
|
+- max_ents--;
|
|
++ max_len -= new_len;
|
|
+ }
|
|
+
|
|
+ return sg_last;
|
|
+diff --git a/drivers/crypto/qce/dma.h b/drivers/crypto/qce/dma.h
|
|
+index 0be71f7f7a58..710d5e370293 100644
|
|
+--- a/drivers/crypto/qce/dma.h
|
|
++++ b/drivers/crypto/qce/dma.h
|
|
+@@ -51,6 +51,6 @@ void qce_dma_issue_pending(struct qce_dma_data *dma);
|
|
+ int qce_dma_terminate_all(struct qce_dma_data *dma);
|
|
+ struct scatterlist *
|
|
+ qce_sgtable_add(struct sg_table *sgt, struct scatterlist *sg_add,
|
|
+- int max_ents);
|
|
++ unsigned int max_len);
|
|
+
|
|
+ #endif /* _DMA_H_ */
|
|
+diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c
|
|
+index 5af74f2431ca..188eb234ba2c 100644
|
|
+--- a/drivers/crypto/qce/skcipher.c
|
|
++++ b/drivers/crypto/qce/skcipher.c
|
|
+@@ -105,13 +105,14 @@ qce_skcipher_async_req_handle(struct crypto_async_request *async_req)
|
|
+
|
|
+ sg_init_one(&rctx->result_sg, qce->dma.result_buf, QCE_RESULT_BUF_SZ);
|
|
+
|
|
+- sg = qce_sgtable_add(&rctx->dst_tbl, req->dst, rctx->dst_nents - 1);
|
|
++ sg = qce_sgtable_add(&rctx->dst_tbl, req->dst, req->cryptlen);
|
|
+ if (IS_ERR(sg)) {
|
|
+ ret = PTR_ERR(sg);
|
|
+ goto error_free;
|
|
+ }
|
|
+
|
|
+- sg = qce_sgtable_add(&rctx->dst_tbl, &rctx->result_sg, 1);
|
|
++ sg = qce_sgtable_add(&rctx->dst_tbl, &rctx->result_sg,
|
|
++ QCE_RESULT_BUF_SZ);
|
|
+ if (IS_ERR(sg)) {
|
|
+ ret = PTR_ERR(sg);
|
|
+ goto error_free;
|
|
diff --git a/target/linux/ipq40xx/patches-4.19/048-crypto-qce-use-AES-fallback-for-small-requests.patch b/target/linux/ipq40xx/patches-4.19/048-crypto-qce-use-AES-fallback-for-small-requests.patch
|
|
new file mode 100644
|
|
index 0000000000..60ebe95c36
|
|
--- /dev/null
|
|
+++ b/target/linux/ipq40xx/patches-4.19/048-crypto-qce-use-AES-fallback-for-small-requests.patch
|
|
@@ -0,0 +1,126 @@
|
|
+From 2d3b6fae7d1a2ad821769440daa91d7eec5c8250 Mon Sep 17 00:00:00 2001
|
|
+From: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+Date: Fri, 20 Dec 2019 09:41:44 -0300
|
|
+Subject: [PATCH] crypto: qce - use AES fallback for small requests
|
|
+
|
|
+Process small blocks using the fallback cipher, as a workaround for an
|
|
+observed failure (DMA-related, apparently) when computing the GCM ghash
|
|
+key. This brings a speed gain as well, since it avoids the latency of
|
|
+using the hardware engine to process small blocks.
|
|
+
|
|
+Using software for all 16-byte requests would be enough to make GCM
|
|
+work, but to increase performance, a larger threshold would be better.
|
|
+Measuring the performance of supported ciphers with openssl speed,
|
|
+software matches hardware at around 768-1024 bytes.
|
|
+
|
|
+Considering the 256-bit ciphers, software is 2-3 times faster than qce
|
|
+at 256-bytes, 30% faster at 512, and about even at 768-bytes. With
|
|
+128-bit keys, the break-even point would be around 1024-bytes.
|
|
+
|
|
+This adds the 'aes_sw_max_len' parameter, to set the largest request
|
|
+length processed by the software fallback. Its default is being set to
|
|
+512 bytes, a little lower than the break-even point, to balance the cost
|
|
+in CPU usage.
|
|
+
|
|
+Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+
|
|
+diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
|
|
+index c1595750864e..a0c4d85de4c3 100644
|
|
+--- a/drivers/crypto/Kconfig
|
|
++++ b/drivers/crypto/Kconfig
|
|
+@@ -640,6 +640,29 @@ choice
|
|
+
|
|
+ endchoice
|
|
+
|
|
++config CRYPTO_DEV_QCE_SW_MAX_LEN
|
|
++ int "Default maximum request size to use software for AES"
|
|
++ depends on CRYPTO_DEV_QCE && CRYPTO_DEV_QCE_SKCIPHER
|
|
++ default 512
|
|
++ help
|
|
++ This sets the default maximum request size to perform AES requests
|
|
++ using software instead of the crypto engine. It can be changed by
|
|
++ setting the aes_sw_max_len parameter.
|
|
++
|
|
++ Small blocks are processed faster in software than hardware.
|
|
++ Considering the 256-bit ciphers, software is 2-3 times faster than
|
|
++ qce at 256-bytes, 30% faster at 512, and about even at 768-bytes.
|
|
++ With 128-bit keys, the break-even point would be around 1024-bytes.
|
|
++
|
|
++ The default is set a little lower, to 512 bytes, to balance the
|
|
++ cost in CPU usage. The minimum recommended setting is 16-bytes
|
|
++ (1 AES block), since AES-GCM will fail if you set it lower.
|
|
++ Setting this to zero will send all requests to the hardware.
|
|
++
|
|
++ Note that 192-bit keys are not supported by the hardware and are
|
|
++ always processed by the software fallback, and all DES requests
|
|
++ are done by the hardware.
|
|
++
|
|
+ config CRYPTO_DEV_QCOM_RNG
|
|
+ tristate "Qualcomm Random Number Generator Driver"
|
|
+ depends on ARCH_QCOM || COMPILE_TEST
|
|
+diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c
|
|
+index 188eb234ba2c..9b72fec2ab2e 100644
|
|
+--- a/drivers/crypto/qce/skcipher.c
|
|
++++ b/drivers/crypto/qce/skcipher.c
|
|
+@@ -13,6 +13,7 @@
|
|
+
|
|
+ #include <linux/device.h>
|
|
+ #include <linux/interrupt.h>
|
|
++#include <linux/moduleparam.h>
|
|
+ #include <linux/types.h>
|
|
+ #include <crypto/aes.h>
|
|
+ #include <crypto/des.h>
|
|
+@@ -20,6 +21,13 @@
|
|
+
|
|
+ #include "cipher.h"
|
|
+
|
|
++static unsigned int aes_sw_max_len = CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN;
|
|
++module_param(aes_sw_max_len, uint, 0644);
|
|
++MODULE_PARM_DESC(aes_sw_max_len,
|
|
++ "Only use hardware for AES requests larger than this "
|
|
++ "[0=always use hardware; anything <16 breaks AES-GCM; default="
|
|
++ __stringify(CONFIG_CRYPTO_DEV_QCE_SOFT_THRESHOLD)"]");
|
|
++
|
|
+ static LIST_HEAD(skcipher_algs);
|
|
+
|
|
+ static void qce_skcipher_done(void *data)
|
|
+@@ -170,15 +178,7 @@ static int qce_skcipher_setkey(struct crypto_skcipher *ablk, const u8 *key,
|
|
+ if (!key || !keylen)
|
|
+ return -EINVAL;
|
|
+
|
|
+- if (IS_AES(flags)) {
|
|
+- switch (IS_XTS(flags) ? keylen >> 1 : keylen) {
|
|
+- case AES_KEYSIZE_128:
|
|
+- case AES_KEYSIZE_256:
|
|
+- break;
|
|
+- default:
|
|
+- goto fallback;
|
|
+- }
|
|
+- } else if (IS_DES(flags)) {
|
|
++ if (IS_DES(flags)) {
|
|
+ u32 tmp[DES_EXPKEY_WORDS];
|
|
+
|
|
+ ret = des_ekey(tmp, key);
|
|
+@@ -189,8 +189,8 @@ static int qce_skcipher_setkey(struct crypto_skcipher *ablk, const u8 *key,
|
|
+
|
|
+ ctx->enc_keylen = keylen;
|
|
+ memcpy(ctx->enc_key, key, keylen);
|
|
+- return 0;
|
|
+-fallback:
|
|
++ if (!IS_AES(flags))
|
|
++ return 0;
|
|
+ ret = crypto_skcipher_setkey(ctx->fallback, key, keylen);
|
|
+ if (!ret)
|
|
+ ctx->enc_keylen = keylen;
|
|
+@@ -213,8 +213,9 @@ static int qce_skcipher_crypt(struct skcipher_request *req, int encrypt)
|
|
+ rctx->flags |= encrypt ? QCE_ENCRYPT : QCE_DECRYPT;
|
|
+ keylen = IS_XTS(rctx->flags) ? ctx->enc_keylen >> 1 : ctx->enc_keylen;
|
|
+
|
|
+- if (IS_AES(rctx->flags) && keylen != AES_KEYSIZE_128 &&
|
|
+- keylen != AES_KEYSIZE_256) {
|
|
++ if (IS_AES(rctx->flags) &&
|
|
++ ((keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_256) ||
|
|
++ req->cryptlen <= aes_sw_max_len)) {
|
|
+ SKCIPHER_REQUEST_ON_STACK(subreq, ctx->fallback);
|
|
+
|
|
+ skcipher_request_set_tfm(subreq, ctx->fallback);
|
|
diff --git a/target/linux/ipq40xx/patches-4.19/049-crypto-qce-handle-AES-XTS-cases-that-qce-fails.patch b/target/linux/ipq40xx/patches-4.19/049-crypto-qce-handle-AES-XTS-cases-that-qce-fails.patch
|
|
new file mode 100644
|
|
index 0000000000..eee2241d19
|
|
--- /dev/null
|
|
+++ b/target/linux/ipq40xx/patches-4.19/049-crypto-qce-handle-AES-XTS-cases-that-qce-fails.patch
|
|
@@ -0,0 +1,59 @@
|
|
+From bbf2b1cf22dc98f3df33b6666df046dfb9564d91 Mon Sep 17 00:00:00 2001
|
|
+From: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+Date: Wed, 5 Feb 2020 13:42:25 -0300
|
|
+Subject: [PATCH] crypto: qce - handle AES-XTS cases that qce fails
|
|
+
|
|
+QCE hangs when presented with an AES-XTS request whose length is larger
|
|
+than QCE_SECTOR_SIZE (512-bytes), and is not a multiple of it. Let the
|
|
+fallback cipher handle them.
|
|
+
|
|
+Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+
|
|
+diff --git a/drivers/crypto/qce/common.c b/drivers/crypto/qce/common.c
|
|
+index 3849d7bcaeb0..3e0fcd7613f1 100644
|
|
+--- a/drivers/crypto/qce/common.c
|
|
++++ b/drivers/crypto/qce/common.c
|
|
+@@ -23,8 +23,6 @@
|
|
+ #include "regs-v5.h"
|
|
+ #include "sha.h"
|
|
+
|
|
+-#define QCE_SECTOR_SIZE 512
|
|
+-
|
|
+ static inline u32 qce_read(struct qce_device *qce, u32 offset)
|
|
+ {
|
|
+ return readl(qce->base + offset);
|
|
+diff --git a/drivers/crypto/qce/common.h b/drivers/crypto/qce/common.h
|
|
+index 3252efa41e7a..5f9d3c4e3ead 100644
|
|
+--- a/drivers/crypto/qce/common.h
|
|
++++ b/drivers/crypto/qce/common.h
|
|
+@@ -20,6 +20,9 @@
|
|
+ #include <crypto/hash.h>
|
|
+ #include <crypto/internal/skcipher.h>
|
|
+
|
|
++/* xts du size */
|
|
++#define QCE_SECTOR_SIZE 512
|
|
++
|
|
+ /* key size in bytes */
|
|
+ #define QCE_SHA_HMAC_KEY_SIZE 64
|
|
+ #define QCE_MAX_CIPHER_KEY_SIZE AES_KEYSIZE_256
|
|
+diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c
|
|
+index 9b72fec2ab2e..e46cb8269640 100644
|
|
+--- a/drivers/crypto/qce/skcipher.c
|
|
++++ b/drivers/crypto/qce/skcipher.c
|
|
+@@ -213,9 +213,14 @@ static int qce_skcipher_crypt(struct skcipher_request *req, int encrypt)
|
|
+ rctx->flags |= encrypt ? QCE_ENCRYPT : QCE_DECRYPT;
|
|
+ keylen = IS_XTS(rctx->flags) ? ctx->enc_keylen >> 1 : ctx->enc_keylen;
|
|
+
|
|
++ /* qce is hanging when AES-XTS request len > QCE_SECTOR_SIZE and
|
|
++ * is not a multiple of it; pass such requests to the fallback
|
|
++ */
|
|
+ if (IS_AES(rctx->flags) &&
|
|
+- ((keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_256) ||
|
|
+- req->cryptlen <= aes_sw_max_len)) {
|
|
++ (((keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_256) ||
|
|
++ req->cryptlen <= aes_sw_max_len) ||
|
|
++ (IS_XTS(rctx->flags) && req->cryptlen > QCE_SECTOR_SIZE &&
|
|
++ req->cryptlen % QCE_SECTOR_SIZE))) {
|
|
+ SKCIPHER_REQUEST_ON_STACK(subreq, ctx->fallback);
|
|
+
|
|
+ skcipher_request_set_tfm(subreq, ctx->fallback);
|
|
diff --git a/target/linux/ipq40xx/patches-4.19/051-crypto-qce-allow-building-only-hashes-ciphers.patch b/target/linux/ipq40xx/patches-4.19/051-crypto-qce-allow-building-only-hashes-ciphers.patch
|
|
new file mode 100644
|
|
index 0000000000..3d4214929c
|
|
--- /dev/null
|
|
+++ b/target/linux/ipq40xx/patches-4.19/051-crypto-qce-allow-building-only-hashes-ciphers.patch
|
|
@@ -0,0 +1,415 @@
|
|
+From 62134842498927a0fcc19798a615340a7a6a9e62 Mon Sep 17 00:00:00 2001
|
|
+From: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+Date: Mon, 28 Oct 2019 15:17:19 -0300
|
|
+Subject: [PATCH] crypto: qce - allow building only hashes/ciphers
|
|
+
|
|
+Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
|
+
|
|
+diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
|
|
+index a8c4ce07fc9d..c1595750864e 100644
|
|
+--- a/drivers/crypto/Kconfig
|
|
++++ b/drivers/crypto/Kconfig
|
|
+@@ -573,6 +573,14 @@ config CRYPTO_DEV_QCE
|
|
+ tristate "Qualcomm crypto engine accelerator"
|
|
+ depends on ARCH_QCOM || COMPILE_TEST
|
|
+ depends on HAS_IOMEM
|
|
++ help
|
|
++ This driver supports Qualcomm crypto engine accelerator
|
|
++ hardware. To compile this driver as a module, choose M here. The
|
|
++ module will be called qcrypto.
|
|
++
|
|
++config CRYPTO_DEV_QCE_SKCIPHER
|
|
++ bool
|
|
++ depends on CRYPTO_DEV_QCE
|
|
+ select CRYPTO_AES
|
|
+ select CRYPTO_DES
|
|
+ select CRYPTO_ECB
|
|
+@@ -580,10 +588,57 @@ config CRYPTO_DEV_QCE
|
|
+ select CRYPTO_XTS
|
|
+ select CRYPTO_CTR
|
|
+ select CRYPTO_BLKCIPHER
|
|
+- help
|
|
+- This driver supports Qualcomm crypto engine accelerator
|
|
+- hardware. To compile this driver as a module, choose M here. The
|
|
+- module will be called qcrypto.
|
|
++
|
|
++config CRYPTO_DEV_QCE_SHA
|
|
++ bool
|
|
++ depends on CRYPTO_DEV_QCE
|
|
++
|
|
++choice
|
|
++ prompt "Algorithms enabled for QCE acceleration"
|
|
++ default CRYPTO_DEV_QCE_ENABLE_ALL
|
|
++ depends on CRYPTO_DEV_QCE
|
|
++ help
|
|
++ This option allows to choose whether to build support for all algorihtms
|
|
++ (default), hashes-only, or skciphers-only.
|
|
++
|
|
++ The QCE engine does not appear to scale as well as the CPU to handle
|
|
++ multiple crypto requests. While the ipq40xx chips have 4-core CPUs, the
|
|
++ QCE handles only 2 requests in parallel.
|
|
++
|
|
++ Ipsec throughput seems to improve when disabling either family of
|
|
++ algorithms, sharing the load with the CPU. Enabling skciphers-only
|
|
++ appears to work best.
|
|
++
|
|
++ config CRYPTO_DEV_QCE_ENABLE_ALL
|
|
++ bool "All supported algorithms"
|
|
++ select CRYPTO_DEV_QCE_SKCIPHER
|
|
++ select CRYPTO_DEV_QCE_SHA
|
|
++ help
|
|
++ Enable all supported algorithms:
|
|
++ - AES (CBC, CTR, ECB, XTS)
|
|
++ - 3DES (CBC, ECB)
|
|
++ - DES (CBC, ECB)
|
|
++ - SHA1, HMAC-SHA1
|
|
++ - SHA256, HMAC-SHA256
|
|
++
|
|
++ config CRYPTO_DEV_QCE_ENABLE_SKCIPHER
|
|
++ bool "Symmetric-key ciphers only"
|
|
++ select CRYPTO_DEV_QCE_SKCIPHER
|
|
++ help
|
|
++ Enable symmetric-key ciphers only:
|
|
++ - AES (CBC, CTR, ECB, XTS)
|
|
++ - 3DES (ECB, CBC)
|
|
++ - DES (ECB, CBC)
|
|
++
|
|
++ config CRYPTO_DEV_QCE_ENABLE_SHA
|
|
++ bool "Hash/HMAC only"
|
|
++ select CRYPTO_DEV_QCE_SHA
|
|
++ help
|
|
++ Enable hashes/HMAC algorithms only:
|
|
++ - SHA1, HMAC-SHA1
|
|
++ - SHA256, HMAC-SHA256
|
|
++
|
|
++endchoice
|
|
+
|
|
+ config CRYPTO_DEV_QCOM_RNG
|
|
+ tristate "Qualcomm Random Number Generator Driver"
|
|
+diff --git a/drivers/crypto/qce/Makefile b/drivers/crypto/qce/Makefile
|
|
+index 8caa04e1ec43..14ade8a7d664 100644
|
|
+--- a/drivers/crypto/qce/Makefile
|
|
++++ b/drivers/crypto/qce/Makefile
|
|
+@@ -2,6 +2,7 @@
|
|
+ obj-$(CONFIG_CRYPTO_DEV_QCE) += qcrypto.o
|
|
+ qcrypto-objs := core.o \
|
|
+ common.o \
|
|
+- dma.o \
|
|
+- sha.o \
|
|
+- skcipher.o
|
|
++ dma.o
|
|
++
|
|
++qcrypto-$(CONFIG_CRYPTO_DEV_QCE_SHA) += sha.o
|
|
++qcrypto-$(CONFIG_CRYPTO_DEV_QCE_SKCIPHER) += skcipher.o
|
|
+diff --git a/drivers/crypto/qce/common.c b/drivers/crypto/qce/common.c
|
|
+index e0202755682b..3849d7bcaeb0 100644
|
|
+--- a/drivers/crypto/qce/common.c
|
|
++++ b/drivers/crypto/qce/common.c
|
|
+@@ -53,52 +53,56 @@ qce_clear_array(struct qce_device *qce, u32 offset, unsigned int len)
|
|
+ qce_write(qce, offset + i * sizeof(u32), 0);
|
|
+ }
|
|
+
|
|
+-static u32 qce_encr_cfg(unsigned long flags, u32 aes_key_size)
|
|
++static u32 qce_config_reg(struct qce_device *qce, int little)
|
|
+ {
|
|
+- u32 cfg = 0;
|
|
++ u32 beats = (qce->burst_size >> 3) - 1;
|
|
++ u32 pipe_pair = qce->pipe_pair_id;
|
|
++ u32 config;
|
|
+
|
|
+- if (IS_AES(flags)) {
|
|
+- if (aes_key_size == AES_KEYSIZE_128)
|
|
+- cfg |= ENCR_KEY_SZ_AES128 << ENCR_KEY_SZ_SHIFT;
|
|
+- else if (aes_key_size == AES_KEYSIZE_256)
|
|
+- cfg |= ENCR_KEY_SZ_AES256 << ENCR_KEY_SZ_SHIFT;
|
|
+- }
|
|
++ config = (beats << REQ_SIZE_SHIFT) & REQ_SIZE_MASK;
|
|
++ config |= BIT(MASK_DOUT_INTR_SHIFT) | BIT(MASK_DIN_INTR_SHIFT) |
|
|
++ BIT(MASK_OP_DONE_INTR_SHIFT) | BIT(MASK_ERR_INTR_SHIFT);
|
|
++ config |= (pipe_pair << PIPE_SET_SELECT_SHIFT) & PIPE_SET_SELECT_MASK;
|
|
++ config &= ~HIGH_SPD_EN_N_SHIFT;
|
|
+
|
|
+- if (IS_AES(flags))
|
|
+- cfg |= ENCR_ALG_AES << ENCR_ALG_SHIFT;
|
|
+- else if (IS_DES(flags) || IS_3DES(flags))
|
|
+- cfg |= ENCR_ALG_DES << ENCR_ALG_SHIFT;
|
|
++ if (little)
|
|
++ config |= BIT(LITTLE_ENDIAN_MODE_SHIFT);
|
|
+
|
|
+- if (IS_DES(flags))
|
|
+- cfg |= ENCR_KEY_SZ_DES << ENCR_KEY_SZ_SHIFT;
|
|
++ return config;
|
|
++}
|
|
+
|
|
+- if (IS_3DES(flags))
|
|
+- cfg |= ENCR_KEY_SZ_3DES << ENCR_KEY_SZ_SHIFT;
|
|
++void qce_cpu_to_be32p_array(__be32 *dst, const u8 *src, unsigned int len)
|
|
++{
|
|
++ __be32 *d = dst;
|
|
++ const u8 *s = src;
|
|
++ unsigned int n;
|
|
+
|
|
+- switch (flags & QCE_MODE_MASK) {
|
|
+- case QCE_MODE_ECB:
|
|
+- cfg |= ENCR_MODE_ECB << ENCR_MODE_SHIFT;
|
|
+- break;
|
|
+- case QCE_MODE_CBC:
|
|
+- cfg |= ENCR_MODE_CBC << ENCR_MODE_SHIFT;
|
|
+- break;
|
|
+- case QCE_MODE_CTR:
|
|
+- cfg |= ENCR_MODE_CTR << ENCR_MODE_SHIFT;
|
|
+- break;
|
|
+- case QCE_MODE_XTS:
|
|
+- cfg |= ENCR_MODE_XTS << ENCR_MODE_SHIFT;
|
|
+- break;
|
|
+- case QCE_MODE_CCM:
|
|
+- cfg |= ENCR_MODE_CCM << ENCR_MODE_SHIFT;
|
|
+- cfg |= LAST_CCM_XFR << LAST_CCM_SHIFT;
|
|
+- break;
|
|
+- default:
|
|
+- return ~0;
|
|
++ n = len / sizeof(u32);
|
|
++ for (; n > 0; n--) {
|
|
++ *d = cpu_to_be32p((const __u32 *) s);
|
|
++ s += sizeof(__u32);
|
|
++ d++;
|
|
+ }
|
|
++}
|
|
+
|
|
+- return cfg;
|
|
++static void qce_setup_config(struct qce_device *qce)
|
|
++{
|
|
++ u32 config;
|
|
++
|
|
++ /* get big endianness */
|
|
++ config = qce_config_reg(qce, 0);
|
|
++
|
|
++ /* clear status */
|
|
++ qce_write(qce, REG_STATUS, 0);
|
|
++ qce_write(qce, REG_CONFIG, config);
|
|
++}
|
|
++
|
|
++static inline void qce_crypto_go(struct qce_device *qce)
|
|
++{
|
|
++ qce_write(qce, REG_GOPROC, BIT(GO_SHIFT) | BIT(RESULTS_DUMP_SHIFT));
|
|
+ }
|
|
+
|
|
++#ifdef CONFIG_CRYPTO_DEV_QCE_SHA
|
|
+ static u32 qce_auth_cfg(unsigned long flags, u32 key_size)
|
|
+ {
|
|
+ u32 cfg = 0;
|
|
+@@ -145,88 +149,6 @@ static u32 qce_auth_cfg(unsigned long flags, u32 key_size)
|
|
+ return cfg;
|
|
+ }
|
|
+
|
|
+-static u32 qce_config_reg(struct qce_device *qce, int little)
|
|
+-{
|
|
+- u32 beats = (qce->burst_size >> 3) - 1;
|
|
+- u32 pipe_pair = qce->pipe_pair_id;
|
|
+- u32 config;
|
|
+-
|
|
+- config = (beats << REQ_SIZE_SHIFT) & REQ_SIZE_MASK;
|
|
+- config |= BIT(MASK_DOUT_INTR_SHIFT) | BIT(MASK_DIN_INTR_SHIFT) |
|
|
+- BIT(MASK_OP_DONE_INTR_SHIFT) | BIT(MASK_ERR_INTR_SHIFT);
|
|
+- config |= (pipe_pair << PIPE_SET_SELECT_SHIFT) & PIPE_SET_SELECT_MASK;
|
|
+- config &= ~HIGH_SPD_EN_N_SHIFT;
|
|
+-
|
|
+- if (little)
|
|
+- config |= BIT(LITTLE_ENDIAN_MODE_SHIFT);
|
|
+-
|
|
+- return config;
|
|
+-}
|
|
+-
|
|
+-void qce_cpu_to_be32p_array(__be32 *dst, const u8 *src, unsigned int len)
|
|
+-{
|
|
+- __be32 *d = dst;
|
|
+- const u8 *s = src;
|
|
+- unsigned int n;
|
|
+-
|
|
+- n = len / sizeof(u32);
|
|
+- for (; n > 0; n--) {
|
|
+- *d = cpu_to_be32p((const __u32 *) s);
|
|
+- s += sizeof(__u32);
|
|
+- d++;
|
|
+- }
|
|
+-}
|
|
+-
|
|
+-static void qce_xts_swapiv(__be32 *dst, const u8 *src, unsigned int ivsize)
|
|
+-{
|
|
+- u8 swap[QCE_AES_IV_LENGTH];
|
|
+- u32 i, j;
|
|
+-
|
|
+- if (ivsize > QCE_AES_IV_LENGTH)
|
|
+- return;
|
|
+-
|
|
+- memset(swap, 0, QCE_AES_IV_LENGTH);
|
|
+-
|
|
+- for (i = (QCE_AES_IV_LENGTH - ivsize), j = ivsize - 1;
|
|
+- i < QCE_AES_IV_LENGTH; i++, j--)
|
|
+- swap[i] = src[j];
|
|
+-
|
|
+- qce_cpu_to_be32p_array(dst, swap, QCE_AES_IV_LENGTH);
|
|
+-}
|
|
+-
|
|
+-static void qce_xtskey(struct qce_device *qce, const u8 *enckey,
|
|
+- unsigned int enckeylen, unsigned int cryptlen)
|
|
+-{
|
|
+- u32 xtskey[QCE_MAX_CIPHER_KEY_SIZE / sizeof(u32)] = {0};
|
|
+- unsigned int xtsklen = enckeylen / (2 * sizeof(u32));
|
|
+- unsigned int xtsdusize;
|
|
+-
|
|
+- qce_cpu_to_be32p_array((__be32 *)xtskey, enckey + enckeylen / 2,
|
|
+- enckeylen / 2);
|
|
+- qce_write_array(qce, REG_ENCR_XTS_KEY0, xtskey, xtsklen);
|
|
+-
|
|
+- /* xts du size 512B */
|
|
+- xtsdusize = min_t(u32, QCE_SECTOR_SIZE, cryptlen);
|
|
+- qce_write(qce, REG_ENCR_XTS_DU_SIZE, xtsdusize);
|
|
+-}
|
|
+-
|
|
+-static void qce_setup_config(struct qce_device *qce)
|
|
+-{
|
|
+- u32 config;
|
|
+-
|
|
+- /* get big endianness */
|
|
+- config = qce_config_reg(qce, 0);
|
|
+-
|
|
+- /* clear status */
|
|
+- qce_write(qce, REG_STATUS, 0);
|
|
+- qce_write(qce, REG_CONFIG, config);
|
|
+-}
|
|
+-
|
|
+-static inline void qce_crypto_go(struct qce_device *qce)
|
|
+-{
|
|
+- qce_write(qce, REG_GOPROC, BIT(GO_SHIFT) | BIT(RESULTS_DUMP_SHIFT));
|
|
+-}
|
|
+-
|
|
+ static int qce_setup_regs_ahash(struct crypto_async_request *async_req,
|
|
+ u32 totallen, u32 offset)
|
|
+ {
|
|
+@@ -311,6 +233,87 @@ static int qce_setup_regs_ahash(struct crypto_async_request *async_req,
|
|
+
|
|
+ return 0;
|
|
+ }
|
|
++#endif
|
|
++
|
|
++#ifdef CONFIG_CRYPTO_DEV_QCE_SKCIPHER
|
|
++static u32 qce_encr_cfg(unsigned long flags, u32 aes_key_size)
|
|
++{
|
|
++ u32 cfg = 0;
|
|
++
|
|
++ if (IS_AES(flags)) {
|
|
++ if (aes_key_size == AES_KEYSIZE_128)
|
|
++ cfg |= ENCR_KEY_SZ_AES128 << ENCR_KEY_SZ_SHIFT;
|
|
++ else if (aes_key_size == AES_KEYSIZE_256)
|
|
++ cfg |= ENCR_KEY_SZ_AES256 << ENCR_KEY_SZ_SHIFT;
|
|
++ }
|
|
++
|
|
++ if (IS_AES(flags))
|
|
++ cfg |= ENCR_ALG_AES << ENCR_ALG_SHIFT;
|
|
++ else if (IS_DES(flags) || IS_3DES(flags))
|
|
++ cfg |= ENCR_ALG_DES << ENCR_ALG_SHIFT;
|
|
++
|
|
++ if (IS_DES(flags))
|
|
++ cfg |= ENCR_KEY_SZ_DES << ENCR_KEY_SZ_SHIFT;
|
|
++
|
|
++ if (IS_3DES(flags))
|
|
++ cfg |= ENCR_KEY_SZ_3DES << ENCR_KEY_SZ_SHIFT;
|
|
++
|
|
++ switch (flags & QCE_MODE_MASK) {
|
|
++ case QCE_MODE_ECB:
|
|
++ cfg |= ENCR_MODE_ECB << ENCR_MODE_SHIFT;
|
|
++ break;
|
|
++ case QCE_MODE_CBC:
|
|
++ cfg |= ENCR_MODE_CBC << ENCR_MODE_SHIFT;
|
|
++ break;
|
|
++ case QCE_MODE_CTR:
|
|
++ cfg |= ENCR_MODE_CTR << ENCR_MODE_SHIFT;
|
|
++ break;
|
|
++ case QCE_MODE_XTS:
|
|
++ cfg |= ENCR_MODE_XTS << ENCR_MODE_SHIFT;
|
|
++ break;
|
|
++ case QCE_MODE_CCM:
|
|
++ cfg |= ENCR_MODE_CCM << ENCR_MODE_SHIFT;
|
|
++ cfg |= LAST_CCM_XFR << LAST_CCM_SHIFT;
|
|
++ break;
|
|
++ default:
|
|
++ return ~0;
|
|
++ }
|
|
++
|
|
++ return cfg;
|
|
++}
|
|
++
|
|
++static void qce_xts_swapiv(__be32 *dst, const u8 *src, unsigned int ivsize)
|
|
++{
|
|
++ u8 swap[QCE_AES_IV_LENGTH];
|
|
++ u32 i, j;
|
|
++
|
|
++ if (ivsize > QCE_AES_IV_LENGTH)
|
|
++ return;
|
|
++
|
|
++ memset(swap, 0, QCE_AES_IV_LENGTH);
|
|
++
|
|
++ for (i = (QCE_AES_IV_LENGTH - ivsize), j = ivsize - 1;
|
|
++ i < QCE_AES_IV_LENGTH; i++, j--)
|
|
++ swap[i] = src[j];
|
|
++
|
|
++ qce_cpu_to_be32p_array(dst, swap, QCE_AES_IV_LENGTH);
|
|
++}
|
|
++
|
|
++static void qce_xtskey(struct qce_device *qce, const u8 *enckey,
|
|
++ unsigned int enckeylen, unsigned int cryptlen)
|
|
++{
|
|
++ u32 xtskey[QCE_MAX_CIPHER_KEY_SIZE / sizeof(u32)] = {0};
|
|
++ unsigned int xtsklen = enckeylen / (2 * sizeof(u32));
|
|
++ unsigned int xtsdusize;
|
|
++
|
|
++ qce_cpu_to_be32p_array((__be32 *)xtskey, enckey + enckeylen / 2,
|
|
++ enckeylen / 2);
|
|
++ qce_write_array(qce, REG_ENCR_XTS_KEY0, xtskey, xtsklen);
|
|
++
|
|
++ /* xts du size 512B */
|
|
++ xtsdusize = min_t(u32, QCE_SECTOR_SIZE, cryptlen);
|
|
++ qce_write(qce, REG_ENCR_XTS_DU_SIZE, xtsdusize);
|
|
++}
|
|
+
|
|
+ static int qce_setup_regs_skcipher(struct crypto_async_request *async_req,
|
|
+ u32 totallen, u32 offset)
|
|
+@@ -392,15 +395,20 @@ static int qce_setup_regs_skcipher(struct crypto_async_request *async_req,
|
|
+
|
|
+ return 0;
|
|
+ }
|
|
++#endif
|
|
+
|
|
+ int qce_start(struct crypto_async_request *async_req, u32 type, u32 totallen,
|
|
+ u32 offset)
|
|
+ {
|
|
+ switch (type) {
|
|
++#ifdef CONFIG_CRYPTO_DEV_QCE_SKCIPHER
|
|
+ case CRYPTO_ALG_TYPE_SKCIPHER:
|
|
+ return qce_setup_regs_skcipher(async_req, totallen, offset);
|
|
++#endif
|
|
++#ifdef CONFIG_CRYPTO_DEV_QCE_SHA
|
|
+ case CRYPTO_ALG_TYPE_AHASH:
|
|
+ return qce_setup_regs_ahash(async_req, totallen, offset);
|
|
++#endif
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+diff --git a/drivers/crypto/qce/core.c b/drivers/crypto/qce/core.c
|
|
+index bf409edc23ab..4ad79b67fc51 100644
|
|
+--- a/drivers/crypto/qce/core.c
|
|
++++ b/drivers/crypto/qce/core.c
|
|
+@@ -30,8 +30,12 @@
|
|
+ #define QCE_QUEUE_LENGTH 1
|
|
+
|
|
+ static const struct qce_algo_ops *qce_ops[] = {
|
|
++#ifdef CONFIG_CRYPTO_DEV_QCE_SKCIPHER
|
|
+ &skcipher_ops,
|
|
++#endif
|
|
++#ifdef CONFIG_CRYPTO_DEV_QCE_SHA
|
|
+ &ahash_ops,
|
|
++#endif
|
|
+ };
|
|
+
|
|
+ static void qce_unregister_algs(struct qce_device *qce)
|
|
diff --git a/target/linux/ipq40xx/patches-4.19/303-spi-nor-enable-4B-opcodes-for-mx25l25635f.patch b/target/linux/ipq40xx/patches-4.19/303-spi-nor-enable-4B-opcodes-for-mx25l25635f.patch
|
|
index 6f7a3a693b..4cabfc8f59 100644
|
|
--- a/target/linux/ipq40xx/patches-4.19/303-spi-nor-enable-4B-opcodes-for-mx25l25635f.patch
|
|
+++ b/target/linux/ipq40xx/patches-4.19/303-spi-nor-enable-4B-opcodes-for-mx25l25635f.patch
|
|
@@ -8,7 +8,7 @@
|
|
{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_4B_OPCODES) },
|
|
{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
|
|
{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
|
|
-@@ -1284,11 +1285,12 @@ static const struct flash_info spi_nor_i
|
|
+@@ -1286,11 +1287,12 @@ static const struct flash_info spi_nor_i
|
|
{ },
|
|
};
|
|
|
|
@@ -23,7 +23,7 @@
|
|
|
|
tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
|
|
if (tmp < 0) {
|
|
-@@ -1299,10 +1301,16 @@ static const struct flash_info *spi_nor_
|
|
+@@ -1301,10 +1303,16 @@ static const struct flash_info *spi_nor_
|
|
for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) {
|
|
info = &spi_nor_ids[tmp];
|
|
if (info->id_len) {
|
|
@@ -42,7 +42,7 @@
|
|
dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n",
|
|
id[0], id[1], id[2]);
|
|
return ERR_PTR(-ENODEV);
|
|
-@@ -2836,7 +2844,7 @@ int spi_nor_scan(struct spi_nor *nor, co
|
|
+@@ -2838,7 +2846,7 @@ int spi_nor_scan(struct spi_nor *nor, co
|
|
info = spi_nor_match_id(name);
|
|
/* Try to auto-detect if chip name wasn't specified or not found */
|
|
if (!info)
|
|
@@ -51,7 +51,7 @@
|
|
if (IS_ERR_OR_NULL(info))
|
|
return -ENOENT;
|
|
|
|
-@@ -2847,7 +2855,7 @@ int spi_nor_scan(struct spi_nor *nor, co
|
|
+@@ -2849,7 +2857,7 @@ int spi_nor_scan(struct spi_nor *nor, co
|
|
if (name && info->id_len) {
|
|
const struct flash_info *jinfo;
|
|
|