From: Robert Marko Date: Sun, 12 Sep 2021 20:20:55 +0000 (+0200) Subject: ipq40xx: 5.10: drop upstreamed patches X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=9fe5516ee569046b2e038b352f593d9ad7f8659f;p=openwrt%2Fstaging%2Faparcar.git ipq40xx: 5.10: drop upstreamed patches Drop patches that have been upstreamed in before 5.10. Signed-off-by: Robert Marko --- diff --git a/target/linux/ipq40xx/patches-5.10/0001-v5.7-ARM-qcom-Add-support-for-IPQ40xx.patch b/target/linux/ipq40xx/patches-5.10/0001-v5.7-ARM-qcom-Add-support-for-IPQ40xx.patch deleted file mode 100644 index 8aa71f360f..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0001-v5.7-ARM-qcom-Add-support-for-IPQ40xx.patch +++ /dev/null @@ -1,42 +0,0 @@ -From f125e2d4339dda6937865f975470b29c84714c9b Mon Sep 17 00:00:00 2001 -From: Christian Lamparter -Date: Mon, 6 Jan 2020 14:57:15 +0100 -Subject: [PATCH] ARM: qcom: Add support for IPQ40xx - -Add support for the Qualcomm IPQ40xx SoC in Kconfig. -Also add its appropriate textofs. - -Signed-off-by: Christian Lamparter -Signed-off-by: John Crispin -Tested-by: Robert Marko -Cc: Luka Perkov -Signed-off-by: Arnd Bergmann ---- - arch/arm/Makefile | 1 + - arch/arm/mach-qcom/Kconfig | 5 +++++ - 2 files changed, 6 insertions(+) - ---- a/arch/arm/Makefile -+++ b/arch/arm/Makefile -@@ -152,6 +152,7 @@ textofs-$(CONFIG_PM_H1940) := 0x001 - ifeq ($(CONFIG_ARCH_SA1100),y) - textofs-$(CONFIG_SA1111) := 0x00208000 - endif -+textofs-$(CONFIG_ARCH_IPQ40XX) := 0x00208000 - textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000 - textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000 - textofs-$(CONFIG_ARCH_MESON) := 0x00208000 ---- a/arch/arm/mach-qcom/Kconfig -+++ b/arch/arm/mach-qcom/Kconfig -@@ -12,6 +12,11 @@ menuconfig ARCH_QCOM - - if ARCH_QCOM - -+config ARCH_IPQ40XX -+ bool "Enable support for IPQ40XX" -+ select CLKSRC_QCOM -+ select HAVE_ARM_ARCH_TIMER -+ - config ARCH_MSM8X60 - bool "Enable support for MSM8X60" - select CLKSRC_QCOM diff --git a/target/linux/ipq40xx/patches-5.10/0002-01-v5.6-regulator-add-IPQ4019-SDHCI-VQMMC-LDO-driver.patch b/target/linux/ipq40xx/patches-5.10/0002-01-v5.6-regulator-add-IPQ4019-SDHCI-VQMMC-LDO-driver.patch deleted file mode 100644 index aaf8c807ed..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0002-01-v5.6-regulator-add-IPQ4019-SDHCI-VQMMC-LDO-driver.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 97043d292365ae39d62b54a6d79dff98d048b501 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Wed, 22 Jan 2020 12:44:14 +0100 -Subject: [PATCH] From ebf652b408200504194be32ad0a3f5bb49d6000a Mon Sep 17 - 00:00:00 2001 From: Robert Marko Date: Sun, 12 Jan - 2020 12:30:01 +0100 Subject: [PATCH] regulator: add IPQ4019 SDHCI VQMMC LDO - driver - -This introduces the IPQ4019 VQMMC LDO driver needed for -the SD/EMMC driver I/O level operation. -This will enable introducing SD/EMMC support for the built-in controller. - -Signed-off-by: Mantas Pucka -Signed-off-by: Robert Marko -Link: https://lore.kernel.org/r/20200112113003.11110-1-robert.marko@sartura.hr -Signed-off-by: Mark Brown ---- - drivers/regulator/Kconfig | 7 ++ - drivers/regulator/Makefile | 1 + - drivers/regulator/vqmmc-ipq4019-regulator.c | 101 ++++++++++++++++++++ - 3 files changed, 109 insertions(+) - create mode 100644 drivers/regulator/vqmmc-ipq4019-regulator.c - ---- a/drivers/regulator/Kconfig -+++ b/drivers/regulator/Kconfig -@@ -1077,6 +1077,13 @@ config REGULATOR_VEXPRESS - This driver provides support for voltage regulators available - on the ARM Ltd's Versatile Express platform. - -+config REGULATOR_VQMMC_IPQ4019 -+ tristate "IPQ4019 VQMMC SD LDO regulator support" -+ depends on ARCH_QCOM -+ help -+ This driver provides support for the VQMMC LDO I/0 -+ voltage regulator of the IPQ4019 SD/EMMC controller. -+ - config REGULATOR_WM831X - tristate "Wolfson Microelectronics WM831x PMIC regulators" - depends on MFD_WM831X ---- a/drivers/regulator/Makefile -+++ b/drivers/regulator/Makefile -@@ -132,6 +132,7 @@ obj-$(CONFIG_REGULATOR_TWL4030) += twl-r - obj-$(CONFIG_REGULATOR_UNIPHIER) += uniphier-regulator.o - obj-$(CONFIG_REGULATOR_VCTRL) += vctrl-regulator.o - obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress-regulator.o -+obj-$(CONFIG_REGULATOR_VQMMC_IPQ4019) += vqmmc-ipq4019-regulator.o - obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o - obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o - obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o ---- /dev/null -+++ b/drivers/regulator/vqmmc-ipq4019-regulator.c -@@ -0,0 +1,101 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+// -+// Copyright (c) 2019 Mantas Pucka -+// Copyright (c) 2019 Robert Marko -+// -+// Driver for IPQ4019 SD/MMC controller's I/O LDO voltage regulator -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static const unsigned int ipq4019_vmmc_voltages[] = { -+ 1500000, 1800000, 2500000, 3000000, -+}; -+ -+static const struct regulator_ops ipq4019_regulator_voltage_ops = { -+ .list_voltage = regulator_list_voltage_table, -+ .map_voltage = regulator_map_voltage_ascend, -+ .get_voltage_sel = regulator_get_voltage_sel_regmap, -+ .set_voltage_sel = regulator_set_voltage_sel_regmap, -+}; -+ -+static const struct regulator_desc vmmc_regulator = { -+ .name = "vmmcq", -+ .ops = &ipq4019_regulator_voltage_ops, -+ .type = REGULATOR_VOLTAGE, -+ .owner = THIS_MODULE, -+ .volt_table = ipq4019_vmmc_voltages, -+ .n_voltages = ARRAY_SIZE(ipq4019_vmmc_voltages), -+ .vsel_reg = 0, -+ .vsel_mask = 0x3, -+}; -+ -+static const struct regmap_config ipq4019_vmmcq_regmap_config = { -+ .reg_bits = 32, -+ .reg_stride = 4, -+ .val_bits = 32, -+}; -+ -+static int ipq4019_regulator_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct regulator_init_data *init_data; -+ struct regulator_config cfg = {}; -+ struct regulator_dev *rdev; -+ struct resource *res; -+ struct regmap *rmap; -+ void __iomem *base; -+ -+ init_data = of_get_regulator_init_data(dev, dev->of_node, -+ &vmmc_regulator); -+ if (!init_data) -+ return -EINVAL; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ base = devm_ioremap_resource(dev, res); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ rmap = devm_regmap_init_mmio(dev, base, &ipq4019_vmmcq_regmap_config); -+ if (IS_ERR(rmap)) -+ return PTR_ERR(rmap); -+ -+ cfg.dev = dev; -+ cfg.init_data = init_data; -+ cfg.of_node = dev->of_node; -+ cfg.regmap = rmap; -+ -+ rdev = devm_regulator_register(dev, &vmmc_regulator, &cfg); -+ if (IS_ERR(rdev)) { -+ dev_err(dev, "Failed to register regulator: %ld\n", -+ PTR_ERR(rdev)); -+ return PTR_ERR(rdev); -+ } -+ platform_set_drvdata(pdev, rdev); -+ -+ return 0; -+} -+ -+static const struct of_device_id regulator_ipq4019_of_match[] = { -+ { .compatible = "qcom,vqmmc-ipq4019-regulator", }, -+ {}, -+}; -+ -+static struct platform_driver ipq4019_regulator_driver = { -+ .probe = ipq4019_regulator_probe, -+ .driver = { -+ .name = "vqmmc-ipq4019-regulator", -+ .of_match_table = of_match_ptr(regulator_ipq4019_of_match), -+ }, -+}; -+module_platform_driver(ipq4019_regulator_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Mantas Pucka "); -+MODULE_DESCRIPTION("IPQ4019 VQMMC voltage regulator"); diff --git a/target/linux/ipq40xx/patches-5.10/0002-02-v5.5-ARM-dts-qcom-ipq4019-Add-SDHCI-controller-node.patch b/target/linux/ipq40xx/patches-5.10/0002-02-v5.5-ARM-dts-qcom-ipq4019-Add-SDHCI-controller-node.patch deleted file mode 100644 index 25fce8daf0..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0002-02-v5.5-ARM-dts-qcom-ipq4019-Add-SDHCI-controller-node.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 04b3b72b5b8fdb883bfdc619cb29b03641b1cc6a Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Thu, 15 Aug 2019 19:28:23 +0200 -Subject: [PATCH] ARM: dts: qcom: ipq4019: Add SDHCI controller node - -IPQ4019 has a built in SD/eMMC controller which is supported by the -SDHCI MSM driver, by the "qcom,sdhci-msm-v4" binding. -So lets add the appropriate node for it. - -Signed-off-by: Robert Marko -Signed-off-by: Bjorn Andersson ---- - arch/arm/boot/dts/qcom-ipq4019.dtsi | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - ---- a/arch/arm/boot/dts/qcom-ipq4019.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -206,6 +206,18 @@ - interrupts = ; - }; - -+ sdhci: sdhci@7824900 { -+ compatible = "qcom,sdhci-msm-v4"; -+ reg = <0x7824900 0x11c>, <0x7824000 0x800>; -+ interrupts = , ; -+ interrupt-names = "hc_irq", "pwr_irq"; -+ bus-width = <8>; -+ clocks = <&gcc GCC_SDCC1_APPS_CLK>, <&gcc GCC_SDCC1_AHB_CLK>, -+ <&gcc GCC_DCD_XO_CLK>; -+ clock-names = "core", "iface", "xo"; -+ status = "disabled"; -+ }; -+ - blsp_dma: dma@7884000 { - compatible = "qcom,bam-v1.7.0"; - reg = <0x07884000 0x23000>; diff --git a/target/linux/ipq40xx/patches-5.10/0003-v5.6-ARM-dts-qcom-Add-nodes-for-SMP-boot-in-IPQ40xx.patch b/target/linux/ipq40xx/patches-5.10/0003-v5.6-ARM-dts-qcom-Add-nodes-for-SMP-boot-in-IPQ40xx.patch deleted file mode 100644 index 3a4127febf..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0003-v5.6-ARM-dts-qcom-Add-nodes-for-SMP-boot-in-IPQ40xx.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 5e4548922009870a38bcf1d887317676d4e08f54 Mon Sep 17 00:00:00 2001 -From: Damir Franusic -Date: Thu, 21 Nov 2019 16:29:02 +0100 -Subject: [PATCH] ARM: dts: qcom: Add nodes for SMP boot in IPQ40xx - -Add missing nodes and properties to enable SMP -support on IPQ40xx devices. - -Booting without "saw_l2" node: - -[ 0.001400] CPU: Testing write buffer coherency: ok -[ 0.001856] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000 -[ 0.060163] Setting up static identity map for 0x80300000 - 0x80300060 -[ 0.080140] rcu: Hierarchical SRCU implementation. -[ 0.120258] smp: Bringing up secondary CPUs ... -[ 0.200540] CPU1: failed to boot: -19 -[ 0.280689] CPU2: failed to boot: -19 -[ 0.360874] CPU3: failed to boot: -19 -[ 0.360966] smp: Brought up 1 node, 1 CPU -[ 0.360979] SMP: Total of 1 processors activated (96.00 BogoMIPS). -[ 0.360988] CPU: All CPU(s) started in SVC mode. - -Then, booting with "saw_l2" node present (this patch applied): - -[ 0.001450] CPU: Testing write buffer coherency: ok -[ 0.001904] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000 -[ 0.060161] Setting up static identity map for 0x80300000 - 0x80300060 -[ 0.080137] rcu: Hierarchical SRCU implementation. -[ 0.120252] smp: Bringing up secondary CPUs ... -[ 0.200958] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001 -[ 0.281091] CPU2: thread -1, cpu 2, socket 0, mpidr 80000002 -[ 0.361264] CPU3: thread -1, cpu 3, socket 0, mpidr 80000003 -[ 0.361430] smp: Brought up 1 node, 4 CPUs -[ 0.361460] SMP: Total of 4 processors activated (384.00 BogoMIPS). -[ 0.361469] CPU: All CPU(s) started in SVC mode. - -Signed-off-by: Damir Franusic -Cc: Luka Perkov -Cc: Robert Marko -Cc: Andy Gross -Cc: Rob Herring -Cc: linux-arm-msm@vger.kernel.org -Link: https://lore.kernel.org/r/20191121152902.21394-1-damir.franusic@gmail.com -Signed-off-by: Bjorn Andersson ---- - arch/arm/boot/dts/qcom-ipq4019.dtsi | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/arch/arm/boot/dts/qcom-ipq4019.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -102,6 +102,7 @@ - L2: l2-cache { - compatible = "cache"; - cache-level = <2>; -+ qcom,saw = <&saw_l2>; - }; - }; - -@@ -353,6 +354,12 @@ - regulator; - }; - -+ saw_l2: regulator@b012000 { -+ compatible = "qcom,saw2"; -+ reg = <0xb012000 0x1000>; -+ regulator; -+ }; -+ - blsp1_uart1: serial@78af000 { - compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; - reg = <0x78af000 0x200>; diff --git a/target/linux/ipq40xx/patches-5.10/0003-v5.7-ARM-dts-qcom-add-gpio-ranges-property.patch b/target/linux/ipq40xx/patches-5.10/0003-v5.7-ARM-dts-qcom-add-gpio-ranges-property.patch deleted file mode 100644 index 6922bc8ff3..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0003-v5.7-ARM-dts-qcom-add-gpio-ranges-property.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 8b99dc0922618062a1589ebd74df6108b4f9ac22 Mon Sep 17 00:00:00 2001 -From: Christian Lamparter -Date: Wed, 8 Jan 2020 13:54:55 +0100 -Subject: [PATCH] ARM: dts: qcom: add gpio-ranges property - -This patch adds the gpio-ranges property to almost all of -the Qualcomm ARM platforms that utilize the pinctrl-msm -framework. - -The gpio-ranges property is part of the gpiolib subsystem. -As a result, the binding text is available in section -"2.1 gpio- and pin-controller interaction" of -Documentation/devicetree/bindings/gpio/gpio.txt - -For more information please see the patch titled: -"pinctrl: msm: fix gpio-hog related boot issues" from -this series. - -Reported-by: Sven Eckelmann -Tested-by: Sven Eckelmann [ipq4019] -Reviewed-by: Bjorn Andersson -Reviewed-by: Linus Walleij -Signed-off-by: Christian Lamparter -Tested-by: Robert Marko [ipq4019] -Cc: Luka Perkov -Signed-off-by: Robert Marko -Link: https://lore.kernel.org/r/20200108125455.308969-1-robert.marko@sartura.hr -Signed-off-by: Bjorn Andersson ---- - arch/arm/boot/dts/qcom-apq8064.dtsi | 1 + - arch/arm/boot/dts/qcom-apq8084.dtsi | 1 + - arch/arm/boot/dts/qcom-ipq4019.dtsi | 1 + - arch/arm/boot/dts/qcom-ipq8064.dtsi | 1 + - arch/arm/boot/dts/qcom-mdm9615.dtsi | 1 + - arch/arm/boot/dts/qcom-msm8660.dtsi | 1 + - arch/arm/boot/dts/qcom-msm8960.dtsi | 1 + - arch/arm/boot/dts/qcom-msm8974.dtsi | 1 + - 8 files changed, 8 insertions(+) - ---- a/arch/arm/boot/dts/qcom-apq8064.dtsi -+++ b/arch/arm/boot/dts/qcom-apq8064.dtsi -@@ -350,6 +350,7 @@ - reg = <0x800000 0x4000>; - - gpio-controller; -+ gpio-ranges = <&tlmm_pinmux 0 0 90>; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; ---- a/arch/arm/boot/dts/qcom-apq8084.dtsi -+++ b/arch/arm/boot/dts/qcom-apq8084.dtsi -@@ -401,6 +401,7 @@ - compatible = "qcom,apq8084-pinctrl"; - reg = <0xfd510000 0x4000>; - gpio-controller; -+ gpio-ranges = <&tlmm 0 0 147>; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; ---- a/arch/arm/boot/dts/qcom-ipq4019.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -201,6 +201,7 @@ - compatible = "qcom,ipq4019-pinctrl"; - reg = <0x01000000 0x300000>; - gpio-controller; -+ gpio-ranges = <&tlmm 0 0 100>; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; ---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi -@@ -119,6 +119,7 @@ - reg = <0x800000 0x4000>; - - gpio-controller; -+ gpio-ranges = <&qcom_pinmux 0 0 69>; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; ---- a/arch/arm/boot/dts/qcom-mdm9615.dtsi -+++ b/arch/arm/boot/dts/qcom-mdm9615.dtsi -@@ -128,6 +128,7 @@ - msmgpio: pinctrl@800000 { - compatible = "qcom,mdm9615-pinctrl"; - gpio-controller; -+ gpio-ranges = <&msmgpio 0 0 88>; - #gpio-cells = <2>; - interrupts = ; - interrupt-controller; ---- a/arch/arm/boot/dts/qcom-msm8660.dtsi -+++ b/arch/arm/boot/dts/qcom-msm8660.dtsi -@@ -115,6 +115,7 @@ - reg = <0x800000 0x4000>; - - gpio-controller; -+ gpio-ranges = <&tlmm 0 0 173>; - #gpio-cells = <2>; - interrupts = <0 16 0x4>; - interrupt-controller; ---- a/arch/arm/boot/dts/qcom-msm8960.dtsi -+++ b/arch/arm/boot/dts/qcom-msm8960.dtsi -@@ -107,6 +107,7 @@ - msmgpio: pinctrl@800000 { - compatible = "qcom,msm8960-pinctrl"; - gpio-controller; -+ gpio-ranges = <&msmgpio 0 0 152>; - #gpio-cells = <2>; - interrupts = <0 16 0x4>; - interrupt-controller; ---- a/arch/arm/boot/dts/qcom-msm8974.dtsi -+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi -@@ -707,6 +707,7 @@ - compatible = "qcom,msm8974-pinctrl"; - reg = <0xfd510000 0x4000>; - gpio-controller; -+ gpio-ranges = <&msmgpio 0 0 146>; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; diff --git a/target/linux/ipq40xx/patches-5.10/0004-v5.8-ARM-dts-qcom-ipq4019-fix-high-resolution-timer.patch b/target/linux/ipq40xx/patches-5.10/0004-v5.8-ARM-dts-qcom-ipq4019-fix-high-resolution-timer.patch deleted file mode 100644 index f82021f4cd..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0004-v5.8-ARM-dts-qcom-ipq4019-fix-high-resolution-timer.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 8acc36189dcaf4487d8c6ba7445948f39b1d248a Mon Sep 17 00:00:00 2001 -From: Abhishek Sahu -Date: Fri, 3 Apr 2020 13:40:40 +0200 -Subject: [PATCH] ARM: dts: qcom: ipq4019: fix high resolution timer - -Cherry-picked from CAF QSDK repo. -Original commit message: -The kernel is failing in switching the timer for high resolution -mode and clock source operates in 10ms resolution. The always-on -property needs to be given for timer device tree node to make -clock source working in 1ns resolution. - -Signed-off-by: Abhishek Sahu -Signed-off-by: Pavel Kubelun -Signed-off-by: Christian Lamparter -Tested-by: Robert Marko -Cc: Luka Perkov -Link: https://lore.kernel.org/r/20200403114040.349787-1-robert.marko@sartura.hr -Signed-off-by: Bjorn Andersson ---- - arch/arm/boot/dts/qcom-ipq4019.dtsi | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm/boot/dts/qcom-ipq4019.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -166,6 +166,7 @@ - <1 4 0xf08>, - <1 1 0xf08>; - clock-frequency = <48000000>; -+ always-on; - }; - - soc { diff --git a/target/linux/ipq40xx/patches-5.10/0005-01-v5.8-net-phy-mdio-add-IPQ4019-MDIO-driver.patch b/target/linux/ipq40xx/patches-5.10/0005-01-v5.8-net-phy-mdio-add-IPQ4019-MDIO-driver.patch deleted file mode 100644 index d678f761f5..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0005-01-v5.8-net-phy-mdio-add-IPQ4019-MDIO-driver.patch +++ /dev/null @@ -1,210 +0,0 @@ -From 466ed24fb22342f3ae1c10758a6a0c6a8c081b2d Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Thu, 30 Apr 2020 11:07:05 +0200 -Subject: [PATCH] net: phy: mdio: add IPQ4019 MDIO driver - -This patch adds the driver for the MDIO interface -inside of Qualcomm IPQ40xx series SoC-s. - -Signed-off-by: Christian Lamparter -Signed-off-by: Robert Marko -Reviewed-by: Andrew Lunn -Reviewed-by: Florian Fainelli -Cc: Luka Perkov -Signed-off-by: David S. Miller ---- - drivers/net/phy/Kconfig | 7 ++ - drivers/net/phy/Makefile | 1 + - drivers/net/phy/mdio-ipq4019.c | 160 +++++++++++++++++++++++++++++++++ - 3 files changed, 168 insertions(+) - create mode 100644 drivers/net/phy/mdio-ipq4019.c - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -156,6 +156,13 @@ config MDIO_I2C - - This is library mode. - -+config MDIO_IPQ4019 -+ tristate "Qualcomm IPQ4019 MDIO interface support" -+ depends on HAS_IOMEM && OF_MDIO -+ help -+ This driver supports the MDIO interface found in Qualcomm -+ IPQ40xx series Soc-s. -+ - config MDIO_MOXART - tristate "MOXA ART MDIO interface support" - depends on ARCH_MOXART || COMPILE_TEST ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -50,6 +50,7 @@ obj-$(CONFIG_MDIO_CAVIUM) += mdio-cavium - obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o - obj-$(CONFIG_MDIO_HISI_FEMAC) += mdio-hisi-femac.o - obj-$(CONFIG_MDIO_I2C) += mdio-i2c.o -+obj-$(CONFIG_MDIO_IPQ4019) += mdio-ipq4019.o - obj-$(CONFIG_MDIO_MOXART) += mdio-moxart.o - obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-mscc-miim.o - obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o ---- /dev/null -+++ b/drivers/net/phy/mdio-ipq4019.c -@@ -0,0 +1,160 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright (c) 2015, The Linux Foundation. All rights reserved. */ -+/* Copyright (c) 2020 Sartura Ltd. */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MDIO_ADDR_REG 0x44 -+#define MDIO_DATA_WRITE_REG 0x48 -+#define MDIO_DATA_READ_REG 0x4c -+#define MDIO_CMD_REG 0x50 -+#define MDIO_CMD_ACCESS_BUSY BIT(16) -+#define MDIO_CMD_ACCESS_START BIT(8) -+#define MDIO_CMD_ACCESS_CODE_READ 0 -+#define MDIO_CMD_ACCESS_CODE_WRITE 1 -+ -+#define ipq4019_MDIO_TIMEOUT 10000 -+#define ipq4019_MDIO_SLEEP 10 -+ -+struct ipq4019_mdio_data { -+ void __iomem *membase; -+}; -+ -+static int ipq4019_mdio_wait_busy(struct mii_bus *bus) -+{ -+ struct ipq4019_mdio_data *priv = bus->priv; -+ unsigned int busy; -+ -+ return readl_poll_timeout(priv->membase + MDIO_CMD_REG, busy, -+ (busy & MDIO_CMD_ACCESS_BUSY) == 0, -+ ipq4019_MDIO_SLEEP, ipq4019_MDIO_TIMEOUT); -+} -+ -+static int ipq4019_mdio_read(struct mii_bus *bus, int mii_id, int regnum) -+{ -+ struct ipq4019_mdio_data *priv = bus->priv; -+ unsigned int cmd; -+ -+ /* Reject clause 45 */ -+ if (regnum & MII_ADDR_C45) -+ return -EOPNOTSUPP; -+ -+ if (ipq4019_mdio_wait_busy(bus)) -+ return -ETIMEDOUT; -+ -+ /* issue the phy address and reg */ -+ writel((mii_id << 8) | regnum, priv->membase + MDIO_ADDR_REG); -+ -+ cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_READ; -+ -+ /* issue read command */ -+ writel(cmd, priv->membase + MDIO_CMD_REG); -+ -+ /* Wait read complete */ -+ if (ipq4019_mdio_wait_busy(bus)) -+ return -ETIMEDOUT; -+ -+ /* Read and return data */ -+ return readl(priv->membase + MDIO_DATA_READ_REG); -+} -+ -+static int ipq4019_mdio_write(struct mii_bus *bus, int mii_id, int regnum, -+ u16 value) -+{ -+ struct ipq4019_mdio_data *priv = bus->priv; -+ unsigned int cmd; -+ -+ /* Reject clause 45 */ -+ if (regnum & MII_ADDR_C45) -+ return -EOPNOTSUPP; -+ -+ if (ipq4019_mdio_wait_busy(bus)) -+ return -ETIMEDOUT; -+ -+ /* issue the phy address and reg */ -+ writel((mii_id << 8) | regnum, priv->membase + MDIO_ADDR_REG); -+ -+ /* issue write data */ -+ writel(value, priv->membase + MDIO_DATA_WRITE_REG); -+ -+ cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_WRITE; -+ /* issue write command */ -+ writel(cmd, priv->membase + MDIO_CMD_REG); -+ -+ /* Wait write complete */ -+ if (ipq4019_mdio_wait_busy(bus)) -+ return -ETIMEDOUT; -+ -+ return 0; -+} -+ -+static int ipq4019_mdio_probe(struct platform_device *pdev) -+{ -+ struct ipq4019_mdio_data *priv; -+ struct mii_bus *bus; -+ int ret; -+ -+ bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(*priv)); -+ if (!bus) -+ return -ENOMEM; -+ -+ priv = bus->priv; -+ -+ priv->membase = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(priv->membase)) -+ return PTR_ERR(priv->membase); -+ -+ bus->name = "ipq4019_mdio"; -+ bus->read = ipq4019_mdio_read; -+ bus->write = ipq4019_mdio_write; -+ bus->parent = &pdev->dev; -+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s%d", pdev->name, pdev->id); -+ -+ ret = of_mdiobus_register(bus, pdev->dev.of_node); -+ if (ret) { -+ dev_err(&pdev->dev, "Cannot register MDIO bus!\n"); -+ return ret; -+ } -+ -+ platform_set_drvdata(pdev, bus); -+ -+ return 0; -+} -+ -+static int ipq4019_mdio_remove(struct platform_device *pdev) -+{ -+ struct mii_bus *bus = platform_get_drvdata(pdev); -+ -+ mdiobus_unregister(bus); -+ -+ return 0; -+} -+ -+static const struct of_device_id ipq4019_mdio_dt_ids[] = { -+ { .compatible = "qcom,ipq4019-mdio" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, ipq4019_mdio_dt_ids); -+ -+static struct platform_driver ipq4019_mdio_driver = { -+ .probe = ipq4019_mdio_probe, -+ .remove = ipq4019_mdio_remove, -+ .driver = { -+ .name = "ipq4019-mdio", -+ .of_match_table = ipq4019_mdio_dt_ids, -+ }, -+}; -+ -+module_platform_driver(ipq4019_mdio_driver); -+ -+MODULE_DESCRIPTION("ipq4019 MDIO interface driver"); -+MODULE_AUTHOR("Qualcomm Atheros"); -+MODULE_LICENSE("Dual BSD/GPL"); diff --git a/target/linux/ipq40xx/patches-5.10/0005-02-v5.8-02-ARM-dts-qcom-ipq4019-add-MDIO-node.patch b/target/linux/ipq40xx/patches-5.10/0005-02-v5.8-02-ARM-dts-qcom-ipq4019-add-MDIO-node.patch deleted file mode 100644 index 1976686e8f..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0005-02-v5.8-02-ARM-dts-qcom-ipq4019-add-MDIO-node.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 9c8c0f70ec6fdac2398632c723c48277be09b7c0 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Thu, 30 Apr 2020 11:07:07 +0200 -Subject: [PATCH] ARM: dts: qcom: ipq4019: add MDIO node - -This patch adds the necessary MDIO interface node -to the Qualcomm IPQ4019 DTSI. - -Built-in QCA8337N switch is managed using it, -and since we have a driver for it lets add it. - -Signed-off-by: Christian Lamparter -Signed-off-by: Robert Marko -Reviewed-by: Andrew Lunn -Reviewed-by: Florian Fainelli -Cc: Luka Perkov -Signed-off-by: David S. Miller ---- - arch/arm/boot/dts/qcom-ipq4019.dtsi | 28 ++++++++++++++++++++++++++++ - 1 file changed, 28 insertions(+) - ---- a/arch/arm/boot/dts/qcom-ipq4019.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -577,5 +577,33 @@ - "legacy"; - status = "disabled"; - }; -+ -+ mdio: mdio@90000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "qcom,ipq4019-mdio"; -+ reg = <0x90000 0x64>; -+ status = "disabled"; -+ -+ ethphy0: ethernet-phy@0 { -+ reg = <0>; -+ }; -+ -+ ethphy1: ethernet-phy@1 { -+ reg = <1>; -+ }; -+ -+ ethphy2: ethernet-phy@2 { -+ reg = <2>; -+ }; -+ -+ ethphy3: ethernet-phy@3 { -+ reg = <3>; -+ }; -+ -+ ethphy4: ethernet-phy@4 { -+ reg = <4>; -+ }; -+ }; - }; - }; diff --git a/target/linux/ipq40xx/patches-5.10/0006-v5.5-crypto-qce-add-CRYPTO_ALG_KERN_DRIVER_ONLY-flag.patch b/target/linux/ipq40xx/patches-5.10/0006-v5.5-crypto-qce-add-CRYPTO_ALG_KERN_DRIVER_ONLY-flag.patch deleted file mode 100644 index 415d6fff99..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0006-v5.5-crypto-qce-add-CRYPTO_ALG_KERN_DRIVER_ONLY-flag.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Eneas U de Queiroz -Subject: [PATCH] crypto: qce - add CRYPTO_ALG_KERN_DRIVER_ONLY flag - -Set the CRYPTO_ALG_KERN_DRIVER_ONLY flag to all algorithms exposed by -the qce driver, since they are all hardware accelerated, accessible -through a kernel driver only, and not available directly to userspace. - -Signed-off-by: Eneas U de Queiroz - ---- a/drivers/crypto/qce/ablkcipher.c -+++ b/drivers/crypto/qce/ablkcipher.c -@@ -380,7 +380,7 @@ static int qce_ablkcipher_register_one(c - - alg->cra_priority = 300; - alg->cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC | -- CRYPTO_ALG_NEED_FALLBACK; -+ 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; ---- a/drivers/crypto/qce/sha.c -+++ b/drivers/crypto/qce/sha.c -@@ -495,7 +495,7 @@ static int qce_ahash_register_one(const - base = &alg->halg.base; - base->cra_blocksize = def->blocksize; - base->cra_priority = 300; -- base->cra_flags = CRYPTO_ALG_ASYNC; -+ base->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY; - base->cra_ctxsize = sizeof(struct qce_sha_ctx); - base->cra_alignmask = 0; - base->cra_module = THIS_MODULE; diff --git a/target/linux/ipq40xx/patches-5.10/0007-v5.5-crypto-qce-switch-to-skcipher-API.patch b/target/linux/ipq40xx/patches-5.10/0007-v5.5-crypto-qce-switch-to-skcipher-API.patch deleted file mode 100644 index 4dcb942150..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0007-v5.5-crypto-qce-switch-to-skcipher-API.patch +++ /dev/null @@ -1,993 +0,0 @@ -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 - ---- 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 ---- a/drivers/crypto/qce/cipher.h -+++ b/drivers/crypto/qce/cipher.h -@@ -45,12 +45,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_ */ ---- a/drivers/crypto/qce/common.c -+++ b/drivers/crypto/qce/common.c -@@ -304,13 +304,13 @@ go_proc: - 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}; -@@ -389,8 +389,8 @@ int qce_start(struct crypto_async_reques - 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: ---- a/drivers/crypto/qce/common.h -+++ b/drivers/crypto/qce/common.h -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - /* key size in bytes */ - #define QCE_SHA_HMAC_KEY_SIZE 64 -@@ -79,7 +80,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; ---- a/drivers/crypto/qce/core.c -+++ b/drivers/crypto/qce/core.c -@@ -22,7 +22,7 @@ - #define QCE_QUEUE_LENGTH 1 - - static const struct qce_algo_ops *qce_ops[] = { -- &ablkcipher_ops, -+ &skcipher_ops, - &ahash_ops, - }; - ---- a/drivers/crypto/qce/ablkcipher.c -+++ /dev/null -@@ -1,440 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-only --/* -- * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. -- */ -- --#include --#include --#include --#include --#include --#include -- --#include "cipher.h" -- --static LIST_HEAD(ablkcipher_algs); -- --static void qce_ablkcipher_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 qce_device *qce = tmpl->qce; -- enum dma_data_direction dir_src, dir_dst; -- u32 status; -- int error; -- bool diff_dst; -- -- 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; -- -- error = qce_dma_terminate_all(&qce->dma); -- if (error) -- dev_dbg(qce->dev, "ablkcipher dma termination error (%d)\n", -- error); -- -- if (diff_dst) -- dma_unmap_sg(qce->dev, rctx->src_sg, rctx->src_nents, dir_src); -- dma_unmap_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst); -- -- sg_free_table(&rctx->dst_tbl); -- -- error = qce_check_status(qce, &status); -- if (error < 0) -- dev_dbg(qce->dev, "ablkcipher 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) --{ -- 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 qce_device *qce = tmpl->qce; -- enum dma_data_direction dir_src, dir_dst; -- struct scatterlist *sg; -- bool diff_dst; -- gfp_t gfp; -- int ret; -- -- rctx->iv = req->info; -- rctx->ivsize = crypto_ablkcipher_ivsize(ablkcipher); -- rctx->cryptlen = req->nbytes; -- -- 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); -- if (diff_dst) -- rctx->dst_nents = sg_nents_for_len(req->dst, req->nbytes); -- else -- rctx->dst_nents = rctx->src_nents; -- if (rctx->src_nents < 0) { -- dev_err(qce->dev, "Invalid numbers of src SG.\n"); -- return rctx->src_nents; -- } -- if (rctx->dst_nents < 0) { -- dev_err(qce->dev, "Invalid numbers of dst SG.\n"); -- return -rctx->dst_nents; -- } -- -- rctx->dst_nents += 1; -- -- gfp = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? -- GFP_KERNEL : GFP_ATOMIC; -- -- ret = sg_alloc_table(&rctx->dst_tbl, rctx->dst_nents, gfp); -- if (ret) -- return ret; -- -- sg_init_one(&rctx->result_sg, qce->dma.result_buf, QCE_RESULT_BUF_SZ); -- -- sg = qce_sgtable_add(&rctx->dst_tbl, req->dst); -- if (IS_ERR(sg)) { -- ret = PTR_ERR(sg); -- goto error_free; -- } -- -- sg = qce_sgtable_add(&rctx->dst_tbl, &rctx->result_sg); -- if (IS_ERR(sg)) { -- ret = PTR_ERR(sg); -- goto error_free; -- } -- -- sg_mark_end(sg); -- rctx->dst_sg = rctx->dst_tbl.sgl; -- -- ret = dma_map_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst); -- if (ret < 0) -- goto error_free; -- -- if (diff_dst) { -- ret = dma_map_sg(qce->dev, req->src, rctx->src_nents, dir_src); -- if (ret < 0) -- goto error_unmap_dst; -- rctx->src_sg = req->src; -- } else { -- rctx->src_sg = rctx->dst_sg; -- } -- -- ret = qce_dma_prep_sgs(&qce->dma, rctx->src_sg, rctx->src_nents, -- rctx->dst_sg, rctx->dst_nents, -- qce_ablkcipher_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); -- if (ret) -- goto error_terminate; -- -- return 0; -- --error_terminate: -- qce_dma_terminate_all(&qce->dma); --error_unmap_src: -- if (diff_dst) -- dma_unmap_sg(qce->dev, req->src, rctx->src_nents, dir_src); --error_unmap_dst: -- dma_unmap_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst); --error_free: -- sg_free_table(&rctx->dst_tbl); -- return ret; --} -- --static int qce_ablkcipher_setkey(struct crypto_ablkcipher *ablk, const u8 *key, -- unsigned int keylen) --{ -- struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ablk); -- struct qce_cipher_ctx *ctx = crypto_tfm_ctx(tfm); -- int ret; -- -- if (!key || !keylen) -- return -EINVAL; -- -- switch (keylen) { -- case AES_KEYSIZE_128: -- case AES_KEYSIZE_256: -- break; -- default: -- goto fallback; -- } -- -- ctx->enc_keylen = keylen; -- memcpy(ctx->enc_key, key, keylen); -- return 0; --fallback: -- ret = crypto_sync_skcipher_setkey(ctx->fallback, key, keylen); -- if (!ret) -- ctx->enc_keylen = keylen; -- return ret; --} -- --static int qce_des_setkey(struct crypto_ablkcipher *ablk, const u8 *key, -- unsigned int keylen) --{ -- struct qce_cipher_ctx *ctx = crypto_ablkcipher_ctx(ablk); -- int err; -- -- err = verify_ablkcipher_des_key(ablk, key); -- if (err) -- return err; -- -- ctx->enc_keylen = keylen; -- memcpy(ctx->enc_key, key, keylen); -- return 0; --} -- --static int qce_des3_setkey(struct crypto_ablkcipher *ablk, const u8 *key, -- unsigned int keylen) --{ -- struct qce_cipher_ctx *ctx = crypto_ablkcipher_ctx(ablk); -- int err; -- -- err = verify_ablkcipher_des3_key(ablk, key); -- if (err) -- return err; -- -- ctx->enc_keylen = keylen; -- memcpy(ctx->enc_key, key, keylen); -- return 0; --} -- --static int qce_ablkcipher_crypt(struct ablkcipher_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 qce_alg_template *tmpl = to_cipher_tmpl(tfm); -- int ret; -- -- rctx->flags = tmpl->alg_flags; -- rctx->flags |= encrypt ? QCE_ENCRYPT : QCE_DECRYPT; -- -- if (IS_AES(rctx->flags) && ctx->enc_keylen != AES_KEYSIZE_128 && -- ctx->enc_keylen != AES_KEYSIZE_256) { -- SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, ctx->fallback); -- -- skcipher_request_set_sync_tfm(subreq, ctx->fallback); -- skcipher_request_set_callback(subreq, req->base.flags, -- NULL, NULL); -- skcipher_request_set_crypt(subreq, req->src, req->dst, -- req->nbytes, req->info); -- ret = encrypt ? crypto_skcipher_encrypt(subreq) : -- crypto_skcipher_decrypt(subreq); -- skcipher_request_zero(subreq); -- return ret; -- } -- -- return tmpl->qce->async_req_enqueue(tmpl->qce, &req->base); --} -- --static int qce_ablkcipher_encrypt(struct ablkcipher_request *req) --{ -- return qce_ablkcipher_crypt(req, 1); --} -- --static int qce_ablkcipher_decrypt(struct ablkcipher_request *req) --{ -- return qce_ablkcipher_crypt(req, 0); --} -- --static int qce_ablkcipher_init(struct crypto_tfm *tfm) --{ -- struct qce_cipher_ctx *ctx = crypto_tfm_ctx(tfm); -- -- memset(ctx, 0, sizeof(*ctx)); -- tfm->crt_ablkcipher.reqsize = sizeof(struct qce_cipher_reqctx); -- -- ctx->fallback = crypto_alloc_sync_skcipher(crypto_tfm_alg_name(tfm), -- 0, CRYPTO_ALG_NEED_FALLBACK); -- return PTR_ERR_OR_ZERO(ctx->fallback); --} -- --static void qce_ablkcipher_exit(struct crypto_tfm *tfm) --{ -- struct qce_cipher_ctx *ctx = crypto_tfm_ctx(tfm); -- -- crypto_free_sync_skcipher(ctx->fallback); --} -- --struct qce_ablkcipher_def { -- unsigned long flags; -- const char *name; -- const char *drv_name; -- unsigned int blocksize; -- unsigned int ivsize; -- unsigned int min_keysize; -- unsigned int max_keysize; --}; -- --static const struct qce_ablkcipher_def ablkcipher_def[] = { -- { -- .flags = QCE_ALG_AES | QCE_MODE_ECB, -- .name = "ecb(aes)", -- .drv_name = "ecb-aes-qce", -- .blocksize = AES_BLOCK_SIZE, -- .ivsize = AES_BLOCK_SIZE, -- .min_keysize = AES_MIN_KEY_SIZE, -- .max_keysize = AES_MAX_KEY_SIZE, -- }, -- { -- .flags = QCE_ALG_AES | QCE_MODE_CBC, -- .name = "cbc(aes)", -- .drv_name = "cbc-aes-qce", -- .blocksize = AES_BLOCK_SIZE, -- .ivsize = AES_BLOCK_SIZE, -- .min_keysize = AES_MIN_KEY_SIZE, -- .max_keysize = AES_MAX_KEY_SIZE, -- }, -- { -- .flags = QCE_ALG_AES | QCE_MODE_CTR, -- .name = "ctr(aes)", -- .drv_name = "ctr-aes-qce", -- .blocksize = AES_BLOCK_SIZE, -- .ivsize = AES_BLOCK_SIZE, -- .min_keysize = AES_MIN_KEY_SIZE, -- .max_keysize = AES_MAX_KEY_SIZE, -- }, -- { -- .flags = QCE_ALG_AES | QCE_MODE_XTS, -- .name = "xts(aes)", -- .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, -- }, -- { -- .flags = QCE_ALG_DES | QCE_MODE_ECB, -- .name = "ecb(des)", -- .drv_name = "ecb-des-qce", -- .blocksize = DES_BLOCK_SIZE, -- .ivsize = 0, -- .min_keysize = DES_KEY_SIZE, -- .max_keysize = DES_KEY_SIZE, -- }, -- { -- .flags = QCE_ALG_DES | QCE_MODE_CBC, -- .name = "cbc(des)", -- .drv_name = "cbc-des-qce", -- .blocksize = DES_BLOCK_SIZE, -- .ivsize = DES_BLOCK_SIZE, -- .min_keysize = DES_KEY_SIZE, -- .max_keysize = DES_KEY_SIZE, -- }, -- { -- .flags = QCE_ALG_3DES | QCE_MODE_ECB, -- .name = "ecb(des3_ede)", -- .drv_name = "ecb-3des-qce", -- .blocksize = DES3_EDE_BLOCK_SIZE, -- .ivsize = 0, -- .min_keysize = DES3_EDE_KEY_SIZE, -- .max_keysize = DES3_EDE_KEY_SIZE, -- }, -- { -- .flags = QCE_ALG_3DES | QCE_MODE_CBC, -- .name = "cbc(des3_ede)", -- .drv_name = "cbc-3des-qce", -- .blocksize = DES3_EDE_BLOCK_SIZE, -- .ivsize = DES3_EDE_BLOCK_SIZE, -- .min_keysize = DES3_EDE_KEY_SIZE, -- .max_keysize = DES3_EDE_KEY_SIZE, -- }, --}; -- --static int qce_ablkcipher_register_one(const struct qce_ablkcipher_def *def, -- struct qce_device *qce) --{ -- struct qce_alg_template *tmpl; -- struct crypto_alg *alg; -- int ret; -- -- tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL); -- if (!tmpl) -- return -ENOMEM; -- -- alg = &tmpl->alg.crypto; -- -- snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", def->name); -- snprintf(alg->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 = IS_3DES(def->flags) ? qce_des3_setkey : -- IS_DES(def->flags) ? qce_des_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(&tmpl->entry); -- tmpl->crypto_alg_type = CRYPTO_ALG_TYPE_ABLKCIPHER; -- tmpl->alg_flags = def->flags; -- tmpl->qce = qce; -- -- ret = crypto_register_alg(alg); -- if (ret) { -- kfree(tmpl); -- dev_err(qce->dev, "%s registration failed\n", alg->cra_name); -- return ret; -- } -- -- list_add_tail(&tmpl->entry, &ablkcipher_algs); -- dev_dbg(qce->dev, "%s is registered\n", alg->cra_name); -- return 0; --} -- --static void qce_ablkcipher_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_del(&tmpl->entry); -- kfree(tmpl); -- } --} -- --static int qce_ablkcipher_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); -- if (ret) -- goto err; -- } -- -- return 0; --err: -- qce_ablkcipher_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, --}; ---- /dev/null -+++ b/drivers/crypto/qce/skcipher.c -@@ -0,0 +1,440 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "cipher.h" -+ -+static LIST_HEAD(skcipher_algs); -+ -+static void qce_skcipher_done(void *data) -+{ -+ struct crypto_async_request *async_req = data; -+ 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; -+ int error; -+ bool diff_dst; -+ -+ 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; -+ -+ error = qce_dma_terminate_all(&qce->dma); -+ if (error) -+ dev_dbg(qce->dev, "skcipher dma termination error (%d)\n", -+ error); -+ -+ if (diff_dst) -+ dma_unmap_sg(qce->dev, rctx->src_sg, rctx->src_nents, dir_src); -+ dma_unmap_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst); -+ -+ sg_free_table(&rctx->dst_tbl); -+ -+ error = qce_check_status(qce, &status); -+ if (error < 0) -+ dev_dbg(qce->dev, "skcipher operation error (%x)\n", status); -+ -+ qce->async_req_done(tmpl->qce, error); -+} -+ -+static int -+qce_skcipher_async_req_handle(struct crypto_async_request *async_req) -+{ -+ 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; -+ bool diff_dst; -+ gfp_t gfp; -+ int ret; -+ -+ 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->cryptlen); -+ if (diff_dst) -+ rctx->dst_nents = sg_nents_for_len(req->dst, req->cryptlen); -+ else -+ rctx->dst_nents = rctx->src_nents; -+ if (rctx->src_nents < 0) { -+ dev_err(qce->dev, "Invalid numbers of src SG.\n"); -+ return rctx->src_nents; -+ } -+ if (rctx->dst_nents < 0) { -+ dev_err(qce->dev, "Invalid numbers of dst SG.\n"); -+ return -rctx->dst_nents; -+ } -+ -+ rctx->dst_nents += 1; -+ -+ gfp = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? -+ GFP_KERNEL : GFP_ATOMIC; -+ -+ ret = sg_alloc_table(&rctx->dst_tbl, rctx->dst_nents, gfp); -+ if (ret) -+ return ret; -+ -+ sg_init_one(&rctx->result_sg, qce->dma.result_buf, QCE_RESULT_BUF_SZ); -+ -+ sg = qce_sgtable_add(&rctx->dst_tbl, req->dst); -+ if (IS_ERR(sg)) { -+ ret = PTR_ERR(sg); -+ goto error_free; -+ } -+ -+ sg = qce_sgtable_add(&rctx->dst_tbl, &rctx->result_sg); -+ if (IS_ERR(sg)) { -+ ret = PTR_ERR(sg); -+ goto error_free; -+ } -+ -+ sg_mark_end(sg); -+ rctx->dst_sg = rctx->dst_tbl.sgl; -+ -+ ret = dma_map_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst); -+ if (ret < 0) -+ goto error_free; -+ -+ if (diff_dst) { -+ ret = dma_map_sg(qce->dev, req->src, rctx->src_nents, dir_src); -+ if (ret < 0) -+ goto error_unmap_dst; -+ rctx->src_sg = req->src; -+ } else { -+ rctx->src_sg = rctx->dst_sg; -+ } -+ -+ ret = qce_dma_prep_sgs(&qce->dma, rctx->src_sg, rctx->src_nents, -+ rctx->dst_sg, rctx->dst_nents, -+ 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->cryptlen, 0); -+ if (ret) -+ goto error_terminate; -+ -+ return 0; -+ -+error_terminate: -+ qce_dma_terminate_all(&qce->dma); -+error_unmap_src: -+ if (diff_dst) -+ dma_unmap_sg(qce->dev, req->src, rctx->src_nents, dir_src); -+error_unmap_dst: -+ dma_unmap_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst); -+error_free: -+ sg_free_table(&rctx->dst_tbl); -+ return ret; -+} -+ -+static int qce_skcipher_setkey(struct crypto_skcipher *ablk, const u8 *key, -+ unsigned int keylen) -+{ -+ struct crypto_tfm *tfm = crypto_skcipher_tfm(ablk); -+ struct qce_cipher_ctx *ctx = crypto_tfm_ctx(tfm); -+ int ret; -+ -+ if (!key || !keylen) -+ return -EINVAL; -+ -+ switch (keylen) { -+ case AES_KEYSIZE_128: -+ case AES_KEYSIZE_256: -+ break; -+ default: -+ goto fallback; -+ } -+ -+ ctx->enc_keylen = keylen; -+ memcpy(ctx->enc_key, key, keylen); -+ return 0; -+fallback: -+ ret = crypto_sync_skcipher_setkey(ctx->fallback, key, keylen); -+ if (!ret) -+ ctx->enc_keylen = keylen; -+ return ret; -+} -+ -+static int qce_des_setkey(struct crypto_skcipher *ablk, const u8 *key, -+ unsigned int keylen) -+{ -+ struct qce_cipher_ctx *ctx = crypto_skcipher_ctx(ablk); -+ int err; -+ -+ err = verify_skcipher_des_key(ablk, key); -+ if (err) -+ return err; -+ -+ ctx->enc_keylen = keylen; -+ memcpy(ctx->enc_key, key, keylen); -+ return 0; -+} -+ -+static int qce_des3_setkey(struct crypto_skcipher *ablk, const u8 *key, -+ unsigned int keylen) -+{ -+ struct qce_cipher_ctx *ctx = crypto_skcipher_ctx(ablk); -+ int err; -+ -+ err = verify_skcipher_des3_key(ablk, key); -+ if (err) -+ return err; -+ -+ ctx->enc_keylen = keylen; -+ memcpy(ctx->enc_key, key, keylen); -+ return 0; -+} -+ -+static int qce_skcipher_crypt(struct skcipher_request *req, int encrypt) -+{ -+ 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; -+ -+ rctx->flags = tmpl->alg_flags; -+ rctx->flags |= encrypt ? QCE_ENCRYPT : QCE_DECRYPT; -+ -+ if (IS_AES(rctx->flags) && ctx->enc_keylen != AES_KEYSIZE_128 && -+ ctx->enc_keylen != AES_KEYSIZE_256) { -+ SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, ctx->fallback); -+ -+ skcipher_request_set_sync_tfm(subreq, ctx->fallback); -+ skcipher_request_set_callback(subreq, req->base.flags, -+ NULL, NULL); -+ skcipher_request_set_crypt(subreq, req->src, req->dst, -+ req->cryptlen, req->iv); -+ ret = encrypt ? crypto_skcipher_encrypt(subreq) : -+ crypto_skcipher_decrypt(subreq); -+ skcipher_request_zero(subreq); -+ return ret; -+ } -+ -+ return tmpl->qce->async_req_enqueue(tmpl->qce, &req->base); -+} -+ -+static int qce_skcipher_encrypt(struct skcipher_request *req) -+{ -+ return qce_skcipher_crypt(req, 1); -+} -+ -+static int qce_skcipher_decrypt(struct skcipher_request *req) -+{ -+ return qce_skcipher_crypt(req, 0); -+} -+ -+static int qce_skcipher_init(struct crypto_skcipher *tfm) -+{ -+ struct qce_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); -+ -+ memset(ctx, 0, sizeof(*ctx)); -+ crypto_skcipher_set_reqsize(tfm, sizeof(struct qce_cipher_reqctx)); -+ -+ ctx->fallback = crypto_alloc_sync_skcipher(crypto_tfm_alg_name(&tfm->base), -+ 0, CRYPTO_ALG_NEED_FALLBACK); -+ return PTR_ERR_OR_ZERO(ctx->fallback); -+} -+ -+static void qce_skcipher_exit(struct crypto_skcipher *tfm) -+{ -+ struct qce_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); -+ -+ crypto_free_sync_skcipher(ctx->fallback); -+} -+ -+struct qce_skcipher_def { -+ unsigned long flags; -+ const char *name; -+ const char *drv_name; -+ unsigned int blocksize; -+ unsigned int ivsize; -+ unsigned int min_keysize; -+ unsigned int max_keysize; -+}; -+ -+static const struct qce_skcipher_def skcipher_def[] = { -+ { -+ .flags = QCE_ALG_AES | QCE_MODE_ECB, -+ .name = "ecb(aes)", -+ .drv_name = "ecb-aes-qce", -+ .blocksize = AES_BLOCK_SIZE, -+ .ivsize = AES_BLOCK_SIZE, -+ .min_keysize = AES_MIN_KEY_SIZE, -+ .max_keysize = AES_MAX_KEY_SIZE, -+ }, -+ { -+ .flags = QCE_ALG_AES | QCE_MODE_CBC, -+ .name = "cbc(aes)", -+ .drv_name = "cbc-aes-qce", -+ .blocksize = AES_BLOCK_SIZE, -+ .ivsize = AES_BLOCK_SIZE, -+ .min_keysize = AES_MIN_KEY_SIZE, -+ .max_keysize = AES_MAX_KEY_SIZE, -+ }, -+ { -+ .flags = QCE_ALG_AES | QCE_MODE_CTR, -+ .name = "ctr(aes)", -+ .drv_name = "ctr-aes-qce", -+ .blocksize = AES_BLOCK_SIZE, -+ .ivsize = AES_BLOCK_SIZE, -+ .min_keysize = AES_MIN_KEY_SIZE, -+ .max_keysize = AES_MAX_KEY_SIZE, -+ }, -+ { -+ .flags = QCE_ALG_AES | QCE_MODE_XTS, -+ .name = "xts(aes)", -+ .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, -+ }, -+ { -+ .flags = QCE_ALG_DES | QCE_MODE_ECB, -+ .name = "ecb(des)", -+ .drv_name = "ecb-des-qce", -+ .blocksize = DES_BLOCK_SIZE, -+ .ivsize = 0, -+ .min_keysize = DES_KEY_SIZE, -+ .max_keysize = DES_KEY_SIZE, -+ }, -+ { -+ .flags = QCE_ALG_DES | QCE_MODE_CBC, -+ .name = "cbc(des)", -+ .drv_name = "cbc-des-qce", -+ .blocksize = DES_BLOCK_SIZE, -+ .ivsize = DES_BLOCK_SIZE, -+ .min_keysize = DES_KEY_SIZE, -+ .max_keysize = DES_KEY_SIZE, -+ }, -+ { -+ .flags = QCE_ALG_3DES | QCE_MODE_ECB, -+ .name = "ecb(des3_ede)", -+ .drv_name = "ecb-3des-qce", -+ .blocksize = DES3_EDE_BLOCK_SIZE, -+ .ivsize = 0, -+ .min_keysize = DES3_EDE_KEY_SIZE, -+ .max_keysize = DES3_EDE_KEY_SIZE, -+ }, -+ { -+ .flags = QCE_ALG_3DES | QCE_MODE_CBC, -+ .name = "cbc(des3_ede)", -+ .drv_name = "cbc-3des-qce", -+ .blocksize = DES3_EDE_BLOCK_SIZE, -+ .ivsize = DES3_EDE_BLOCK_SIZE, -+ .min_keysize = DES3_EDE_KEY_SIZE, -+ .max_keysize = DES3_EDE_KEY_SIZE, -+ }, -+}; -+ -+static int qce_skcipher_register_one(const struct qce_skcipher_def *def, -+ struct qce_device *qce) -+{ -+ struct qce_alg_template *tmpl; -+ struct skcipher_alg *alg; -+ int ret; -+ -+ tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL); -+ if (!tmpl) -+ return -ENOMEM; -+ -+ alg = &tmpl->alg.skcipher; -+ -+ 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->base.cra_blocksize = def->blocksize; -+ alg->ivsize = def->ivsize; -+ alg->min_keysize = def->min_keysize; -+ alg->max_keysize = def->max_keysize; -+ alg->setkey = IS_3DES(def->flags) ? qce_des3_setkey : -+ IS_DES(def->flags) ? qce_des_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_SKCIPHER; -+ tmpl->alg_flags = def->flags; -+ tmpl->qce = qce; -+ -+ ret = crypto_register_skcipher(alg); -+ if (ret) { -+ kfree(tmpl); -+ dev_err(qce->dev, "%s registration failed\n", alg->base.cra_name); -+ return ret; -+ } -+ -+ list_add_tail(&tmpl->entry, &skcipher_algs); -+ dev_dbg(qce->dev, "%s is registered\n", alg->base.cra_name); -+ return 0; -+} -+ -+static void qce_skcipher_unregister(struct qce_device *qce) -+{ -+ struct qce_alg_template *tmpl, *n; -+ -+ 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_skcipher_register(struct qce_device *qce) -+{ -+ int ret, i; -+ -+ 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_skcipher_unregister(qce); -+ return ret; -+} -+ -+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-5.10/0008-v5.6-crypto-qce-fix-ctr-aes-qce-block-chunk-sizes.patch b/target/linux/ipq40xx/patches-5.10/0008-v5.6-crypto-qce-fix-ctr-aes-qce-block-chunk-sizes.patch deleted file mode 100644 index ac4f163f4a..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0008-v5.6-crypto-qce-fix-ctr-aes-qce-block-chunk-sizes.patch +++ /dev/null @@ -1,43 +0,0 @@ -From bb5c863b3d3cbd10e80b2ebf409934a091058f54 Mon Sep 17 00:00:00 2001 -From: Eneas U de Queiroz -Date: Fri, 20 Dec 2019 16:02:13 -0300 -Subject: [PATCH 02/11] 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 -Signed-off-by: Herbert Xu ---- - drivers/crypto/qce/skcipher.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/crypto/qce/skcipher.c -+++ b/drivers/crypto/qce/skcipher.c -@@ -270,6 +270,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; -@@ -298,7 +299,8 @@ static const struct qce_skcipher_def skc - .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, -@@ -368,6 +370,7 @@ static int qce_skcipher_register_one(con - 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-5.10/0009-v5.6-crypto-qce-fix-xts-aes-qce-key-sizes.patch b/target/linux/ipq40xx/patches-5.10/0009-v5.6-crypto-qce-fix-xts-aes-qce-key-sizes.patch deleted file mode 100644 index 4dcf1ac726..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0009-v5.6-crypto-qce-fix-xts-aes-qce-key-sizes.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 7de4c2bd196f111e39cc60f6197654aff23ba2b4 Mon Sep 17 00:00:00 2001 -From: Eneas U de Queiroz -Date: Fri, 20 Dec 2019 16:02:14 -0300 -Subject: [PATCH 03/11] 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 -Signed-off-by: Herbert Xu ---- - drivers/crypto/qce/skcipher.c | 13 ++++++++----- - 1 file changed, 8 insertions(+), 5 deletions(-) - ---- a/drivers/crypto/qce/skcipher.c -+++ b/drivers/crypto/qce/skcipher.c -@@ -154,12 +154,13 @@ static int qce_skcipher_setkey(struct cr - { - struct crypto_tfm *tfm = crypto_skcipher_tfm(ablk); - struct qce_cipher_ctx *ctx = crypto_tfm_ctx(tfm); -+ unsigned long flags = to_cipher_tmpl(ablk)->alg_flags; - int ret; - - if (!key || !keylen) - return -EINVAL; - -- switch (keylen) { -+ switch (IS_XTS(flags) ? keylen >> 1 : keylen) { - case AES_KEYSIZE_128: - case AES_KEYSIZE_256: - break; -@@ -213,13 +214,15 @@ static int qce_skcipher_crypt(struct skc - 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) { - SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, ctx->fallback); - - skcipher_request_set_sync_tfm(subreq, ctx->fallback); -@@ -311,8 +314,8 @@ static const struct qce_skcipher_def skc - .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-5.10/0010-v5.6-crypto-qce-save-a-sg-table-slot-for-result-buf.patch b/target/linux/ipq40xx/patches-5.10/0010-v5.6-crypto-qce-save-a-sg-table-slot-for-result-buf.patch deleted file mode 100644 index 2385d483f2..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0010-v5.6-crypto-qce-save-a-sg-table-slot-for-result-buf.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 3ee50c896d712dc2fc8f34c2cd1918d035e74045 Mon Sep 17 00:00:00 2001 -From: Eneas U de Queiroz -Date: Fri, 20 Dec 2019 16:02:15 -0300 -Subject: [PATCH 04/11] 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 sg 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 buffer. - -When copying the sg table, there's no limit to the number of entries -copied, so the 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 -Signed-off-by: Herbert Xu ---- - drivers/crypto/qce/dma.c | 6 ++++-- - drivers/crypto/qce/dma.h | 3 ++- - drivers/crypto/qce/skcipher.c | 4 ++-- - 3 files changed, 8 insertions(+), 5 deletions(-) - ---- a/drivers/crypto/qce/dma.c -+++ b/drivers/crypto/qce/dma.c -@@ -47,7 +47,8 @@ void qce_dma_release(struct qce_dma_data - } - - 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; - -@@ -60,12 +61,13 @@ qce_sgtable_add(struct sg_table *sgt, st - 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; ---- a/drivers/crypto/qce/dma.h -+++ b/drivers/crypto/qce/dma.h -@@ -42,6 +42,7 @@ int qce_dma_prep_sgs(struct qce_dma_data - 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_ */ ---- a/drivers/crypto/qce/skcipher.c -+++ b/drivers/crypto/qce/skcipher.c -@@ -95,13 +95,13 @@ qce_skcipher_async_req_handle(struct cry - - 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-5.10/0011-v5.6-crypto-qce-update-the-skcipher-IV.patch b/target/linux/ipq40xx/patches-5.10/0011-v5.6-crypto-qce-update-the-skcipher-IV.patch deleted file mode 100644 index 5efdb72c44..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0011-v5.6-crypto-qce-update-the-skcipher-IV.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 3e806a12d10af2581aa26c37b58439286eab9782 Mon Sep 17 00:00:00 2001 -From: Eneas U de Queiroz -Date: Fri, 20 Dec 2019 16:02:16 -0300 -Subject: [PATCH 05/11] crypto: qce - update the skcipher IV - -Update the IV after the completion of each cipher operation. - -Signed-off-by: Eneas U de Queiroz -Signed-off-by: Herbert Xu ---- - drivers/crypto/qce/skcipher.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/crypto/qce/skcipher.c -+++ b/drivers/crypto/qce/skcipher.c -@@ -21,6 +21,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; -@@ -45,6 +46,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-5.10/0012-v5.6-crypto-qce-initialize-fallback-only-for-AES.patch b/target/linux/ipq40xx/patches-5.10/0012-v5.6-crypto-qce-initialize-fallback-only-for-AES.patch deleted file mode 100644 index 84aef04ef4..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0012-v5.6-crypto-qce-initialize-fallback-only-for-AES.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 8ceda883205db6dfedb82e39f67feae3b50c95a1 Mon Sep 17 00:00:00 2001 -From: Eneas U de Queiroz -Date: Fri, 20 Dec 2019 16:02:17 -0300 -Subject: [PATCH 06/11] 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 other algorithms. - -Signed-off-by: Eneas U de Queiroz -Signed-off-by: Herbert Xu ---- - drivers/crypto/qce/skcipher.c | 17 ++++++++++++++--- - 1 file changed, 14 insertions(+), 3 deletions(-) - ---- a/drivers/crypto/qce/skcipher.c -+++ b/drivers/crypto/qce/skcipher.c -@@ -257,7 +257,14 @@ static int qce_skcipher_init(struct cryp - - 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); - -+ qce_skcipher_init(tfm); - ctx->fallback = crypto_alloc_sync_skcipher(crypto_tfm_alg_name(&tfm->base), - 0, CRYPTO_ALG_NEED_FALLBACK); - return PTR_ERR_OR_ZERO(ctx->fallback); -@@ -387,14 +394,18 @@ static int qce_skcipher_register_one(con - - 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-5.10/0013-v5.6-crypto-qce-allow-building-only-hashes-ciphers.patch b/target/linux/ipq40xx/patches-5.10/0013-v5.6-crypto-qce-allow-building-only-hashes-ciphers.patch deleted file mode 100644 index 5b1372d08f..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0013-v5.6-crypto-qce-allow-building-only-hashes-ciphers.patch +++ /dev/null @@ -1,419 +0,0 @@ -From 59e056cda4beb5412e3653e6360c2eb0fa770baa Mon Sep 17 00:00:00 2001 -From: Eneas U de Queiroz -Date: Fri, 20 Dec 2019 16:02:18 -0300 -Subject: [PATCH 07/11] crypto: qce - allow building only hashes/ciphers - -Allow the user to choose whether to build support for all algorithms -(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. - -Signed-off-by: Eneas U de Queiroz -Signed-off-by: Herbert Xu ---- - ---- a/drivers/crypto/Kconfig -+++ b/drivers/crypto/Kconfig -@@ -617,6 +617,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_LIB_DES - select CRYPTO_ECB -@@ -624,10 +632,57 @@ config CRYPTO_DEV_QCE - select CRYPTO_XTS - select CRYPTO_CTR - select CRYPTO_BLKCIPHER -+ -+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 driver supports Qualcomm crypto engine accelerator -- hardware. To compile this driver as a module, choose M here. The -- module will be called qcrypto. -+ 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" ---- 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 ---- a/drivers/crypto/qce/common.c -+++ b/drivers/crypto/qce/common.c -@@ -45,52 +45,56 @@ qce_clear_array(struct qce_device *qce, - 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; -@@ -137,88 +141,6 @@ static u32 qce_auth_cfg(unsigned long fl - 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) - { -@@ -303,6 +225,87 @@ go_proc: - - 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) -@@ -384,15 +387,20 @@ static int qce_setup_regs_skcipher(struc - - 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; - } ---- a/drivers/crypto/qce/core.c -+++ b/drivers/crypto/qce/core.c -@@ -22,8 +22,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-5.10/0014-v5.7-crypto-qce-use-cryptlen-when-adding-extra-sgl.patch b/target/linux/ipq40xx/patches-5.10/0014-v5.7-crypto-qce-use-cryptlen-when-adding-extra-sgl.patch deleted file mode 100644 index 160420b485..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0014-v5.7-crypto-qce-use-cryptlen-when-adding-extra-sgl.patch +++ /dev/null @@ -1,89 +0,0 @@ -From d6364b8128439a8c0e381f80c38667de9f15eef8 Mon Sep 17 00:00:00 2001 -From: Eneas U de Queiroz -Date: Fri, 7 Feb 2020 12:02:25 -0300 -Subject: [PATCH 09/11] 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 -Signed-off-by: Herbert Xu ---- - drivers/crypto/qce/dma.c | 11 ++++++----- - drivers/crypto/qce/dma.h | 2 +- - drivers/crypto/qce/skcipher.c | 5 +++-- - 3 files changed, 10 insertions(+), 8 deletions(-) - ---- a/drivers/crypto/qce/dma.c -+++ b/drivers/crypto/qce/dma.c -@@ -48,9 +48,10 @@ void qce_dma_release(struct qce_dma_data - - 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)) -@@ -61,13 +62,13 @@ qce_sgtable_add(struct sg_table *sgt, st - 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; ---- a/drivers/crypto/qce/dma.h -+++ b/drivers/crypto/qce/dma.h -@@ -43,6 +43,6 @@ void qce_dma_issue_pending(struct qce_dm - 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_ */ ---- a/drivers/crypto/qce/skcipher.c -+++ b/drivers/crypto/qce/skcipher.c -@@ -97,13 +97,14 @@ qce_skcipher_async_req_handle(struct cry - - 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-5.10/0015-v5.7-crypto-qce-use-AES-fallback-for-small-requests.patch b/target/linux/ipq40xx/patches-5.10/0015-v5.7-crypto-qce-use-AES-fallback-for-small-requests.patch deleted file mode 100644 index 0b5c8c6d66..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0015-v5.7-crypto-qce-use-AES-fallback-for-small-requests.patch +++ /dev/null @@ -1,113 +0,0 @@ -From ce163ba0bf298f1707321ac025ef639f88e62801 Mon Sep 17 00:00:00 2001 -From: Eneas U de Queiroz -Date: Fri, 7 Feb 2020 12:02:26 -0300 -Subject: [PATCH 10/11] 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 -Signed-off-by: Herbert Xu ---- - ---- a/drivers/crypto/Kconfig -+++ b/drivers/crypto/Kconfig -@@ -684,6 +684,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 ---- a/drivers/crypto/qce/skcipher.c -+++ b/drivers/crypto/qce/skcipher.c -@@ -5,6 +5,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -12,6 +13,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) -@@ -166,15 +174,10 @@ static int qce_skcipher_setkey(struct cr - switch (IS_XTS(flags) ? keylen >> 1 : keylen) { - case AES_KEYSIZE_128: - case AES_KEYSIZE_256: -+ memcpy(ctx->enc_key, key, keylen); - break; -- default: -- goto fallback; - } - -- ctx->enc_keylen = keylen; -- memcpy(ctx->enc_key, key, keylen); -- return 0; --fallback: - ret = crypto_sync_skcipher_setkey(ctx->fallback, key, keylen); - if (!ret) - ctx->enc_keylen = keylen; -@@ -224,8 +227,9 @@ static int qce_skcipher_crypt(struct skc - 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)) { - SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, ctx->fallback); - - skcipher_request_set_sync_tfm(subreq, ctx->fallback); diff --git a/target/linux/ipq40xx/patches-5.10/0016-v5.7-crypto-qce-handle-AES-XTS-cases-that-qce-fails.patch b/target/linux/ipq40xx/patches-5.10/0016-v5.7-crypto-qce-handle-AES-XTS-cases-that-qce-fails.patch deleted file mode 100644 index 18beda6296..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0016-v5.7-crypto-qce-handle-AES-XTS-cases-that-qce-fails.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 7f19380b2cfd412dcef2facefb3f6c62788864d7 Mon Sep 17 00:00:00 2001 -From: Eneas U de Queiroz -Date: Fri, 7 Feb 2020 12:02:27 -0300 -Subject: [PATCH 11/11] 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 -Signed-off-by: Herbert Xu ---- - drivers/crypto/qce/common.c | 2 -- - drivers/crypto/qce/common.h | 3 +++ - drivers/crypto/qce/skcipher.c | 9 +++++++-- - 3 files changed, 10 insertions(+), 4 deletions(-) - ---- a/drivers/crypto/qce/common.c -+++ b/drivers/crypto/qce/common.c -@@ -15,8 +15,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); ---- a/drivers/crypto/qce/common.h -+++ b/drivers/crypto/qce/common.h -@@ -12,6 +12,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 ---- a/drivers/crypto/qce/skcipher.c -+++ b/drivers/crypto/qce/skcipher.c -@@ -227,9 +227,14 @@ static int qce_skcipher_crypt(struct skc - 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))) { - SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, ctx->fallback); - - skcipher_request_set_sync_tfm(subreq, ctx->fallback); diff --git a/target/linux/ipq40xx/patches-5.10/0017-v5.8-phy-add-driver-for-Qualcomm-IPQ40xx-USB-PHY.patch b/target/linux/ipq40xx/patches-5.10/0017-v5.8-phy-add-driver-for-Qualcomm-IPQ40xx-USB-PHY.patch deleted file mode 100644 index ad09a9f250..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0017-v5.8-phy-add-driver-for-Qualcomm-IPQ40xx-USB-PHY.patch +++ /dev/null @@ -1,197 +0,0 @@ -From 3c9d8f6c03a2cda1849ec3c84f82ec030d1f49ef Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Sun, 3 May 2020 22:18:22 +0200 -Subject: [PATCH] phy: add driver for Qualcomm IPQ40xx USB PHY - -Add a driver to setup the USB PHY-s on Qualcom m IPQ40xx series SoCs. -The driver sets up HS and SS phys. - -Signed-off-by: John Crispin -Signed-off-by: Robert Marko -Cc: Luka Perkov -Link: https://lore.kernel.org/r/20200503201823.531757-1-robert.marko@sartura.hr -Signed-off-by: Vinod Koul ---- - drivers/phy/qualcomm/Kconfig | 7 + - drivers/phy/qualcomm/Makefile | 1 + - drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c | 148 ++++++++++++++++++++ - 3 files changed, 156 insertions(+) - create mode 100644 drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c - ---- a/drivers/phy/qualcomm/Kconfig -+++ b/drivers/phy/qualcomm/Kconfig -@@ -18,6 +18,13 @@ config PHY_QCOM_APQ8064_SATA - depends on OF - select GENERIC_PHY - -+config PHY_QCOM_IPQ4019_USB -+ tristate "Qualcomm IPQ4019 USB PHY driver" -+ depends on OF && (ARCH_QCOM || COMPILE_TEST) -+ select GENERIC_PHY -+ help -+ Support for the USB PHY-s on Qualcomm IPQ40xx SoC-s. -+ - config PHY_QCOM_IPQ806X_SATA - tristate "Qualcomm IPQ806x SATA SerDes/PHY driver" - depends on ARCH_QCOM ---- a/drivers/phy/qualcomm/Makefile -+++ b/drivers/phy/qualcomm/Makefile -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - obj-$(CONFIG_PHY_ATH79_USB) += phy-ath79-usb.o - obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o -+obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o - obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o - obj-$(CONFIG_PHY_QCOM_PCIE2) += phy-qcom-pcie2.o - obj-$(CONFIG_PHY_QCOM_QMP) += phy-qcom-qmp.o ---- /dev/null -+++ b/drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c -@@ -0,0 +1,148 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (C) 2018 John Crispin -+ * -+ * Based on code from -+ * Allwinner Technology Co., Ltd. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct ipq4019_usb_phy { -+ struct device *dev; -+ struct phy *phy; -+ void __iomem *base; -+ struct reset_control *por_rst; -+ struct reset_control *srif_rst; -+}; -+ -+static int ipq4019_ss_phy_power_off(struct phy *_phy) -+{ -+ struct ipq4019_usb_phy *phy = phy_get_drvdata(_phy); -+ -+ reset_control_assert(phy->por_rst); -+ msleep(10); -+ -+ return 0; -+} -+ -+static int ipq4019_ss_phy_power_on(struct phy *_phy) -+{ -+ struct ipq4019_usb_phy *phy = phy_get_drvdata(_phy); -+ -+ ipq4019_ss_phy_power_off(_phy); -+ -+ reset_control_deassert(phy->por_rst); -+ -+ return 0; -+} -+ -+static struct phy_ops ipq4019_usb_ss_phy_ops = { -+ .power_on = ipq4019_ss_phy_power_on, -+ .power_off = ipq4019_ss_phy_power_off, -+}; -+ -+static int ipq4019_hs_phy_power_off(struct phy *_phy) -+{ -+ struct ipq4019_usb_phy *phy = phy_get_drvdata(_phy); -+ -+ reset_control_assert(phy->por_rst); -+ msleep(10); -+ -+ reset_control_assert(phy->srif_rst); -+ msleep(10); -+ -+ return 0; -+} -+ -+static int ipq4019_hs_phy_power_on(struct phy *_phy) -+{ -+ struct ipq4019_usb_phy *phy = phy_get_drvdata(_phy); -+ -+ ipq4019_hs_phy_power_off(_phy); -+ -+ reset_control_deassert(phy->srif_rst); -+ msleep(10); -+ -+ reset_control_deassert(phy->por_rst); -+ -+ return 0; -+} -+ -+static struct phy_ops ipq4019_usb_hs_phy_ops = { -+ .power_on = ipq4019_hs_phy_power_on, -+ .power_off = ipq4019_hs_phy_power_off, -+}; -+ -+static const struct of_device_id ipq4019_usb_phy_of_match[] = { -+ { .compatible = "qcom,usb-hs-ipq4019-phy", .data = &ipq4019_usb_hs_phy_ops}, -+ { .compatible = "qcom,usb-ss-ipq4019-phy", .data = &ipq4019_usb_ss_phy_ops}, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, ipq4019_usb_phy_of_match); -+ -+static int ipq4019_usb_phy_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct resource *res; -+ struct phy_provider *phy_provider; -+ struct ipq4019_usb_phy *phy; -+ -+ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); -+ if (!phy) -+ return -ENOMEM; -+ -+ phy->dev = &pdev->dev; -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ phy->base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(phy->base)) { -+ dev_err(dev, "failed to remap register memory\n"); -+ return PTR_ERR(phy->base); -+ } -+ -+ phy->por_rst = devm_reset_control_get(phy->dev, "por_rst"); -+ if (IS_ERR(phy->por_rst)) { -+ if (PTR_ERR(phy->por_rst) != -EPROBE_DEFER) -+ dev_err(dev, "POR reset is missing\n"); -+ return PTR_ERR(phy->por_rst); -+ } -+ -+ phy->srif_rst = devm_reset_control_get_optional(phy->dev, "srif_rst"); -+ if (IS_ERR(phy->srif_rst)) -+ return PTR_ERR(phy->srif_rst); -+ -+ phy->phy = devm_phy_create(dev, NULL, of_device_get_match_data(dev)); -+ if (IS_ERR(phy->phy)) { -+ dev_err(dev, "failed to create PHY\n"); -+ return PTR_ERR(phy->phy); -+ } -+ phy_set_drvdata(phy->phy, phy); -+ -+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); -+ -+ return PTR_ERR_OR_ZERO(phy_provider); -+} -+ -+static struct platform_driver ipq4019_usb_phy_driver = { -+ .probe = ipq4019_usb_phy_probe, -+ .driver = { -+ .of_match_table = ipq4019_usb_phy_of_match, -+ .name = "ipq4019-usb-phy", -+ } -+}; -+module_platform_driver(ipq4019_usb_phy_driver); -+ -+MODULE_DESCRIPTION("QCOM/IPQ4019 USB phy driver"); -+MODULE_AUTHOR("John Crispin "); -+MODULE_LICENSE("GPL v2"); diff --git a/target/linux/ipq40xx/patches-5.10/0018-v5.9-pinctrl-msm-open-drain.patch b/target/linux/ipq40xx/patches-5.10/0018-v5.9-pinctrl-msm-open-drain.patch deleted file mode 100644 index 5cd4ccc30f..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0018-v5.9-pinctrl-msm-open-drain.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 5b08c1d567ee8e6af94696b3e549997cbdb2bb80 Mon Sep 17 00:00:00 2001 -From: Jaiganesh Narayanan -Date: Thu, 1 Sep 2016 10:40:38 +0530 -Subject: [PATCH] pinctrl: qcom: ipq4019: add open drain support - -Signed-off-by: Jaiganesh Narayanan -[ Brian: adapted from from the Chromium OS kernel used on IPQ4019-based - WiFi APs. ] -Signed-off-by: Brian Norris ---- -https://lore.kernel.org/linux-gpio/20200703080646.23233-1-computersforpeace@gmail.com/ - - drivers/pinctrl/qcom/pinctrl-ipq4019.c | 1 + - drivers/pinctrl/qcom/pinctrl-msm.c | 13 +++++++++++++ - drivers/pinctrl/qcom/pinctrl-msm.h | 2 ++ - 3 files changed, 16 insertions(+) - ---- a/drivers/pinctrl/qcom/pinctrl-ipq4019.c -+++ b/drivers/pinctrl/qcom/pinctrl-ipq4019.c -@@ -254,6 +254,7 @@ DECLARE_QCA_GPIO_PINS(99); - .mux_bit = 2, \ - .pull_bit = 0, \ - .drv_bit = 6, \ -+ .od_bit = 12, \ - .oe_bit = 9, \ - .in_bit = 0, \ - .out_bit = 1, \ ---- a/drivers/pinctrl/qcom/pinctrl-msm.c -+++ b/drivers/pinctrl/qcom/pinctrl-msm.c -@@ -225,6 +225,10 @@ static int msm_config_reg(struct msm_pin - *bit = g->pull_bit; - *mask = 3; - break; -+ case PIN_CONFIG_DRIVE_OPEN_DRAIN: -+ *bit = g->od_bit; -+ *mask = 1; -+ break; - case PIN_CONFIG_DRIVE_STRENGTH: - *bit = g->drv_bit; - *mask = 7; -@@ -302,6 +306,12 @@ static int msm_config_group_get(struct p - if (!arg) - return -EINVAL; - break; -+ case PIN_CONFIG_DRIVE_OPEN_DRAIN: -+ /* Pin is not open-drain */ -+ if (!arg) -+ return -EINVAL; -+ arg = 1; -+ break; - case PIN_CONFIG_DRIVE_STRENGTH: - arg = msm_regval_to_drive(arg); - break; -@@ -374,6 +384,9 @@ static int msm_config_group_set(struct p - else - arg = MSM_PULL_UP; - break; -+ case PIN_CONFIG_DRIVE_OPEN_DRAIN: -+ arg = 1; -+ break; - case PIN_CONFIG_DRIVE_STRENGTH: - /* Check for invalid values */ - if (arg > 16 || arg < 2 || (arg % 2) != 0) ---- a/drivers/pinctrl/qcom/pinctrl-msm.h -+++ b/drivers/pinctrl/qcom/pinctrl-msm.h -@@ -38,6 +38,7 @@ struct msm_function { - * @mux_bit: Offset in @ctl_reg for the pinmux function selection. - * @pull_bit: Offset in @ctl_reg for the bias configuration. - * @drv_bit: Offset in @ctl_reg for the drive strength configuration. -+ * @od_bit: Offset in @ctl_reg for controlling open drain. - * @oe_bit: Offset in @ctl_reg for controlling output enable. - * @in_bit: Offset in @io_reg for the input bit value. - * @out_bit: Offset in @io_reg for the output bit value. -@@ -75,6 +76,7 @@ struct msm_pingroup { - unsigned pull_bit:5; - unsigned drv_bit:5; - -+ unsigned od_bit:5; - unsigned oe_bit:5; - unsigned in_bit:5; - unsigned out_bit:5; diff --git a/target/linux/ipq40xx/patches-5.10/0019-v5.6-mtd-spi-nor-Add-support-for-mx25r3235f.patch b/target/linux/ipq40xx/patches-5.10/0019-v5.6-mtd-spi-nor-Add-support-for-mx25r3235f.patch deleted file mode 100644 index f1be01c8e1..0000000000 --- a/target/linux/ipq40xx/patches-5.10/0019-v5.6-mtd-spi-nor-Add-support-for-mx25r3235f.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 707745e8d4e75b638b990d67950ab292b3b8ea2a Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Mon, 16 Dec 2019 01:36:46 +0100 -Subject: [PATCH] mtd: spi-nor: Add support for mx25r3235f - -Add MTD support for the Macronix MX25R3235F SPI NOR chip from Macronix. -The chip has 4MB of total capacity, divided into a total of 64 sectors, -each 64KB sized. The chip also supports 4KB large sectors. -Additionally, it supports dual and quad read modes. - -Functionality was verified on an HPE/Aruba AP-303 board. - -Signed-off-by: David Bauer -Signed-off-by: Tudor Ambarus ---- - drivers/mtd/spi-nor/spi-nor.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/mtd/spi-nor/spi-nor.c -+++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -2353,6 +2353,8 @@ static const struct flash_info spi_nor_i - { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) }, - { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, - { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, -+ { "mx25r3235f", INFO(0xc22816, 0, 64 * 1024, 64, -+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "mx25u12835f", INFO(0xc22538, 0, 64 * 1024, 256, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512,