diff --git a/diff.diff b/diff.diff deleted file mode 100644 index dc3fac8f10..0000000000 --- a/diff.diff +++ /dev/null @@ -1,4329 +0,0 @@ -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 -+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 -+--- -+ -+--- a/backport-include/linux/pci.h -++++ b/backport-include/linux/pci.h -+@@ -3,6 +3,10 @@ -+ #include_next -+ #include -+ -++#if LINUX_VERSION_IS_LESS(5,4,0) -++#include -++#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 -+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 -+--- -+ -+--- 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 -+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 -+Tested-by: Christoph Krapp -+ -+--- 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 -+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 -+--- -+ -+--- 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 - 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 "Nps is running." - msgstr "Nps 运行中" - - msgid "Nps is not running." --msgstr "Nps 未运行" -\ No newline at end of file -+msgstr "Nps 未运行" -+ -+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 -+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 -+Tested-by: Rafał Miłecki -+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 -+Signed-off-by: David S. Miller -+--- -+ 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?= -+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 -+--- -+ 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 -+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 -+Signed-off-by: Tudor Ambarus -+--- -+ 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 -+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 -+Acked-by: Matt Ranostay -+Signed-off-by: Jonathan Cameron -+--- -+ 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 -+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 -+Signed-off-by: Jonathan Cameron -+--- -+ 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 -++ * -++ * 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 -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#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 "); -++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 -+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 -+Tested-by: Andreas Brauchli -+Signed-off-by: Jonathan Cameron -+--- -+ 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 -+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 -+Signed-off-by: Jonathan Cameron -+--- -+ 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 -+ * -+ * I2C slave address: 0x69 -+- * -+- * TODO: -+- * - support for reading/setting auto cleaning interval -+ */ -+ -+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+@@ -21,6 +18,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ -+ #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 -+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 -+Signed-off-by: Jonathan Cameron -+--- -+ 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 -+ #include -+ #include -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 -+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 -+Signed-off-by: Jonathan Cameron -+--- -+ 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 -+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 -+Cc: Andreas Brauchli -+Acked-by: Tomasz Duszynski -+--- -+ 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 -+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 -+Acked-by: Tomasz Duszynski -+--- -+ 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?= -+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 -+--- -+ 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 -+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 -+Tested-by: Rafał Miłecki -+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 -+Signed-off-by: David S. Miller -+--- -+ 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 - + 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 - 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 - + - + 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 - - 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 - + 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 --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 ----- -- 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 -+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 -+--- -+ 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 - } - --- 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 - 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 - 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 -+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 -+ -+Signed-off-by: Konstantin Vasin -+--- -+ -+--- 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 -+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 -+ -+Signed-off-by: Konstantin Vasin -+--- -+ -+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 - + 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 - - --- 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 - 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 - - --- 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 - - --- 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 - 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 - 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 - - --- 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 - 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 - 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 - 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 - #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 - 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 - #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 -+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 -+Signed-off-by: Ard Biesheuvel -+Backported-to-4.19-by: Eneas U de Queiroz -+ -+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 -+ #include -+ #include -++#include -+ -+ /* 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 -+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 -+ -+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 -+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 -+ -+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 -+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 -+ -+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 -+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 -+ -+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 -+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 -+ -+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 -+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 -+ -+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 -+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 -+ -+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 -+ #include -++#include -+ #include -+ #include -+ #include -+@@ -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 -+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 -+ -+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 -+ #include -+ -++/* 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 -+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 -+ -+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; -