aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mediatek/patches-5.4
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/mediatek/patches-5.4')
-rw-r--r--target/linux/mediatek/patches-5.4/0001-v5.7-spi-make-spi-max-frequency-optional.patch38
-rw-r--r--target/linux/mediatek/patches-5.4/0002-v5.7-spi-add-support-for-mediatek-spi-nor-controller.patch761
-rw-r--r--target/linux/mediatek/patches-5.4/0003-switch-add-mt7531.patch19
-rw-r--r--target/linux/mediatek/patches-5.4/0005-dts-mt7622-add-gsw.patch258
-rw-r--r--target/linux/mediatek/patches-5.4/0005-dts-mt7629-add-gsw.patch90
-rw-r--r--target/linux/mediatek/patches-5.4/0006-dts-fix-bpi2-console.patch10
-rw-r--r--target/linux/mediatek/patches-5.4/0006-dts-fix-bpi64-console.patch11
-rw-r--r--target/linux/mediatek/patches-5.4/0010-dts-mt7629-rfb-fix-firmware-partition.patch13
-rw-r--r--target/linux/mediatek/patches-5.4/0226-phy-phy-mtk-tphy-Add-hifsys-support.patch66
-rw-r--r--target/linux/mediatek/patches-5.4/0301-mtd-mtk-ecc-move-mtk-ecc-header-file-to-include-mtd.patch139
-rw-r--r--target/linux/mediatek/patches-5.4/0303-mtd-spinand-disable-on-die-ECC.patch31
-rw-r--r--target/linux/mediatek/patches-5.4/0306-spi-spi-mem-MediaTek-Add-SPI-NAND-Flash-interface-dr.patch1246
-rw-r--r--target/linux/mediatek/patches-5.4/0307-dts-mt7629-add-snand-support.patch97
-rw-r--r--target/linux/mediatek/patches-5.4/0308-dts-mt7622-add-snand-support.patch96
-rw-r--r--target/linux/mediatek/patches-5.4/0310-dts-add-wmac-support-for-mt7622-rfb1.patch40
-rw-r--r--target/linux/mediatek/patches-5.4/0310-mtk-bmt-support.patch837
-rw-r--r--target/linux/mediatek/patches-5.4/0350-mtd-parsers-trx-Allow-to-specify-trx-magic-in-DT.patch75
-rw-r--r--target/linux/mediatek/patches-5.4/0351-mtd-parsers-Remove-dependency-to-BRCM-architectures.patch23
-rw-r--r--target/linux/mediatek/patches-5.4/0500-v5.6-crypto-backport-inside-secure.patch5464
-rw-r--r--target/linux/mediatek/patches-5.4/0501-crypto-add-eip97-inside-secure-support.patch27
-rw-r--r--target/linux/mediatek/patches-5.4/0502-dts-mt7623-eip97-inside-secure-support.patch23
-rw-r--r--target/linux/mediatek/patches-5.4/0503-crypto-fix-eip97-cache-incoherent.patch26
-rw-r--r--target/linux/mediatek/patches-5.4/0600-net-phylink-propagate-resolved-link-config-via-mac_l.patch246
-rw-r--r--target/linux/mediatek/patches-5.4/0601-net-dsa-propagate-resolved-link-config-via-mac_link_.patch143
-rw-r--r--target/linux/mediatek/patches-5.4/0602-net-dsa-mt7530-use-resolved-link-config-in-mac_link_.patch145
-rw-r--r--target/linux/mediatek/patches-5.4/0603-net-dsa-mt7530-Extend-device-data-ready-for-adding-a.patch458
-rw-r--r--target/linux/mediatek/patches-5.4/0604-net-dsa-mt7530-Add-the-support-of-MT7531-switch.patch1510
-rw-r--r--target/linux/mediatek/patches-5.4/0605-arm64-dts-mt7622-add-mt7531-dsa-to-bananapi-bpi-r64-board.patch71
-rw-r--r--target/linux/mediatek/patches-5.4/0900-bt-mtk-serial-fix.patch33
-rw-r--r--target/linux/mediatek/patches-5.4/0990-gsw-rtl8367s-mt7622-support.patch23
-rw-r--r--target/linux/mediatek/patches-5.4/0991-dt-bindings-PCI-Mediatek-Update-PCIe-binding.patch415
-rw-r--r--target/linux/mediatek/patches-5.4/0992-PCI-mediatek-Use-regmap-to-get-shared-pcie-cfg-base.patch217
-rw-r--r--target/linux/mediatek/patches-5.4/0993-arm64-dts-mediatek-Split-PCIe-node-for-MT2712-MT7622.patch417
-rw-r--r--target/linux/mediatek/patches-5.4/0994-ARM-dts-mediatek-Update-mt7629-PCIe-node.patch203
-rw-r--r--target/linux/mediatek/patches-5.4/1003-dts-mt7622-rfb-change-to-ax-mtd-layout.patch23
-rw-r--r--target/linux/mediatek/patches-5.4/1010-pcie-mediatek-fix-clearing-interrupt-status.patch24
-rw-r--r--target/linux/mediatek/patches-5.4/1011-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch85
-rw-r--r--target/linux/mediatek/patches-5.4/1012-pci-pcie-mediatek-add-support-for-coherent-DMA.patch108
-rw-r--r--target/linux/mediatek/patches-5.4/1020-spi-nor-w25q512jv.patch25
-rw-r--r--target/linux/mediatek/patches-5.4/1021-ubnt-ledbar-driver.patch29
-rw-r--r--target/linux/mediatek/patches-5.4/115-dts-bpi64-add-snand-support.patch57
41 files changed, 0 insertions, 13622 deletions
diff --git a/target/linux/mediatek/patches-5.4/0001-v5.7-spi-make-spi-max-frequency-optional.patch b/target/linux/mediatek/patches-5.4/0001-v5.7-spi-make-spi-max-frequency-optional.patch
deleted file mode 100644
index 79ce15c37b..0000000000
--- a/target/linux/mediatek/patches-5.4/0001-v5.7-spi-make-spi-max-frequency-optional.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 671c3bf50ae498dc12aef6c70abe5cfa066b1348 Mon Sep 17 00:00:00 2001
-From: Chuanhong Guo <gch981213@gmail.com>
-Date: Fri, 6 Mar 2020 16:50:49 +0800
-Subject: [PATCH 1/2] spi: make spi-max-frequency optional
-
-We only need a spi-max-frequency when we specifically request a
-spi frequency lower than the max speed of spi host.
-This property is already documented as optional property and current
-host drivers are implemented to operate at highest speed possible
-when spi->max_speed_hz is 0.
-This patch makes spi-max-frequency an optional property so that
-we could just omit it to use max controller speed.
-
-Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
-Link: https://lore.kernel.org/r/20200306085052.28258-2-gch981213@gmail.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spi.c | 9 ++-------
- 1 file changed, 2 insertions(+), 7 deletions(-)
-
---- a/drivers/spi/spi.c
-+++ b/drivers/spi/spi.c
-@@ -1809,13 +1809,8 @@ static int of_spi_parse_dt(struct spi_co
- spi->mode |= SPI_CS_HIGH;
-
- /* Device speed */
-- rc = of_property_read_u32(nc, "spi-max-frequency", &value);
-- if (rc) {
-- dev_err(&ctlr->dev,
-- "%pOF has no valid 'spi-max-frequency' property (%d)\n", nc, rc);
-- return rc;
-- }
-- spi->max_speed_hz = value;
-+ if (!of_property_read_u32(nc, "spi-max-frequency", &value))
-+ spi->max_speed_hz = value;
-
- return 0;
- }
diff --git a/target/linux/mediatek/patches-5.4/0002-v5.7-spi-add-support-for-mediatek-spi-nor-controller.patch b/target/linux/mediatek/patches-5.4/0002-v5.7-spi-add-support-for-mediatek-spi-nor-controller.patch
deleted file mode 100644
index 0a63bdddaf..0000000000
--- a/target/linux/mediatek/patches-5.4/0002-v5.7-spi-add-support-for-mediatek-spi-nor-controller.patch
+++ /dev/null
@@ -1,761 +0,0 @@
-From 881d1ee9fe81ff2be1b90809a07621be97404a57 Mon Sep 17 00:00:00 2001
-From: Chuanhong Guo <gch981213@gmail.com>
-Date: Fri, 6 Mar 2020 16:50:50 +0800
-Subject: [PATCH 2/2] spi: add support for mediatek spi-nor controller
-
-This is a driver for mtk spi-nor controller using spi-mem interface.
-The same controller already has limited support provided by mtk-quadspi
-driver under spi-nor framework and this new driver is a replacement
-for the old one.
-
-Comparing to the old driver, this driver has following advantages:
-1. It can handle any full-duplex spi transfer up to 6 bytes, and
- this is implemented using generic spi interface.
-2. It take account into command opcode properly. The reading routine
- in this controller can only use 0x03 or 0x0b as opcode on 1-1-1
- transfers, but old driver doesn't implement this properly. This
- driver checks supported opcode explicitly and use (1) to perform
- unmatched operations.
-3. It properly handles SFDP reading. Old driver can't read SFDP
- due to the bug mentioned in (2).
-4. It can do 1-2-2 and 1-4-4 fast reading on spi-nor. These two ops
- requires parsing SFDP, which isn't possible in old driver. And
- the old driver is only flagged to support 1-1-2 mode.
-5. It takes advantage of the DMA feature in this controller for
- long reads and supports IRQ on DMA requests to free cpu cycles
- from polling status registers on long DMA reading. It achieves
- up to 17.5MB/s reading speed (1-4-4 mode) which is way faster
- than the old one. IRQ is implemented as optional to maintain
- backward compatibility.
-
-Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
-Link: https://lore.kernel.org/r/20200306085052.28258-3-gch981213@gmail.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/Kconfig | 10 +
- drivers/spi/Makefile | 1 +
- drivers/spi/spi-mtk-nor.c | 689 ++++++++++++++++++++++++++++++++++++++
- 3 files changed, 700 insertions(+)
- create mode 100644 drivers/spi/spi-mtk-nor.c
-
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -433,6 +433,16 @@ config SPI_MT7621
- help
- This selects a driver for the MediaTek MT7621 SPI Controller.
-
-+config SPI_MTK_NOR
-+ tristate "MediaTek SPI NOR controller"
-+ depends on ARCH_MEDIATEK || COMPILE_TEST
-+ help
-+ This enables support for SPI NOR controller found on MediaTek
-+ ARM SoCs. This is a controller specifically for SPI-NOR flash.
-+ It can perform generic SPI transfers up to 6 bytes via generic
-+ SPI interface as well as several SPI-NOR specific instructions
-+ via SPI MEM interface.
-+
- config SPI_NPCM_FIU
- tristate "Nuvoton NPCM FLASH Interface Unit"
- depends on ARCH_NPCM || COMPILE_TEST
---- a/drivers/spi/Makefile
-+++ b/drivers/spi/Makefile
-@@ -61,6 +61,7 @@ obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mp
- obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o
- obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o
- obj-$(CONFIG_SPI_MT7621) += spi-mt7621.o
-+obj-$(CONFIG_SPI_MTK_NOR) += spi-mtk-nor.o
- obj-$(CONFIG_SPI_MXIC) += spi-mxic.o
- obj-$(CONFIG_SPI_MXS) += spi-mxs.o
- obj-$(CONFIG_SPI_NPCM_FIU) += spi-npcm-fiu.o
---- /dev/null
-+++ b/drivers/spi/spi-mtk-nor.c
-@@ -0,0 +1,689 @@
-+// SPDX-License-Identifier: GPL-2.0
-+//
-+// Mediatek SPI NOR controller driver
-+//
-+// Copyright (C) 2020 Chuanhong Guo <gch981213@gmail.com>
-+
-+#include <linux/bits.h>
-+#include <linux/clk.h>
-+#include <linux/completion.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/iopoll.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of_device.h>
-+#include <linux/spi/spi.h>
-+#include <linux/spi/spi-mem.h>
-+#include <linux/string.h>
-+
-+#define DRIVER_NAME "mtk-spi-nor"
-+
-+#define MTK_NOR_REG_CMD 0x00
-+#define MTK_NOR_CMD_WRITE BIT(4)
-+#define MTK_NOR_CMD_PROGRAM BIT(2)
-+#define MTK_NOR_CMD_READ BIT(0)
-+#define MTK_NOR_CMD_MASK GENMASK(5, 0)
-+
-+#define MTK_NOR_REG_PRG_CNT 0x04
-+#define MTK_NOR_REG_RDATA 0x0c
-+
-+#define MTK_NOR_REG_RADR0 0x10
-+#define MTK_NOR_REG_RADR(n) (MTK_NOR_REG_RADR0 + 4 * (n))
-+#define MTK_NOR_REG_RADR3 0xc8
-+
-+#define MTK_NOR_REG_WDATA 0x1c
-+
-+#define MTK_NOR_REG_PRGDATA0 0x20
-+#define MTK_NOR_REG_PRGDATA(n) (MTK_NOR_REG_PRGDATA0 + 4 * (n))
-+#define MTK_NOR_REG_PRGDATA_MAX 5
-+
-+#define MTK_NOR_REG_SHIFT0 0x38
-+#define MTK_NOR_REG_SHIFT(n) (MTK_NOR_REG_SHIFT0 + 4 * (n))
-+#define MTK_NOR_REG_SHIFT_MAX 9
-+
-+#define MTK_NOR_REG_CFG1 0x60
-+#define MTK_NOR_FAST_READ BIT(0)
-+
-+#define MTK_NOR_REG_CFG2 0x64
-+#define MTK_NOR_WR_CUSTOM_OP_EN BIT(4)
-+#define MTK_NOR_WR_BUF_EN BIT(0)
-+
-+#define MTK_NOR_REG_PP_DATA 0x98
-+
-+#define MTK_NOR_REG_IRQ_STAT 0xa8
-+#define MTK_NOR_REG_IRQ_EN 0xac
-+#define MTK_NOR_IRQ_DMA BIT(7)
-+#define MTK_NOR_IRQ_MASK GENMASK(7, 0)
-+
-+#define MTK_NOR_REG_CFG3 0xb4
-+#define MTK_NOR_DISABLE_WREN BIT(7)
-+#define MTK_NOR_DISABLE_SR_POLL BIT(5)
-+
-+#define MTK_NOR_REG_WP 0xc4
-+#define MTK_NOR_ENABLE_SF_CMD 0x30
-+
-+#define MTK_NOR_REG_BUSCFG 0xcc
-+#define MTK_NOR_4B_ADDR BIT(4)
-+#define MTK_NOR_QUAD_ADDR BIT(3)
-+#define MTK_NOR_QUAD_READ BIT(2)
-+#define MTK_NOR_DUAL_ADDR BIT(1)
-+#define MTK_NOR_DUAL_READ BIT(0)
-+#define MTK_NOR_BUS_MODE_MASK GENMASK(4, 0)
-+
-+#define MTK_NOR_REG_DMA_CTL 0x718
-+#define MTK_NOR_DMA_START BIT(0)
-+
-+#define MTK_NOR_REG_DMA_FADR 0x71c
-+#define MTK_NOR_REG_DMA_DADR 0x720
-+#define MTK_NOR_REG_DMA_END_DADR 0x724
-+
-+#define MTK_NOR_PRG_MAX_SIZE 6
-+// Reading DMA src/dst addresses have to be 16-byte aligned
-+#define MTK_NOR_DMA_ALIGN 16
-+#define MTK_NOR_DMA_ALIGN_MASK (MTK_NOR_DMA_ALIGN - 1)
-+// and we allocate a bounce buffer if destination address isn't aligned.
-+#define MTK_NOR_BOUNCE_BUF_SIZE PAGE_SIZE
-+
-+// Buffered page program can do one 128-byte transfer
-+#define MTK_NOR_PP_SIZE 128
-+
-+#define CLK_TO_US(sp, clkcnt) ((clkcnt) * 1000000 / sp->spi_freq)
-+
-+struct mtk_nor {
-+ struct spi_controller *ctlr;
-+ struct device *dev;
-+ void __iomem *base;
-+ u8 *buffer;
-+ struct clk *spi_clk;
-+ struct clk *ctlr_clk;
-+ unsigned int spi_freq;
-+ bool wbuf_en;
-+ bool has_irq;
-+ struct completion op_done;
-+};
-+
-+static inline void mtk_nor_rmw(struct mtk_nor *sp, u32 reg, u32 set, u32 clr)
-+{
-+ u32 val = readl(sp->base + reg);
-+
-+ val &= ~clr;
-+ val |= set;
-+ writel(val, sp->base + reg);
-+}
-+
-+static inline int mtk_nor_cmd_exec(struct mtk_nor *sp, u32 cmd, ulong clk)
-+{
-+ ulong delay = CLK_TO_US(sp, clk);
-+ u32 reg;
-+ int ret;
-+
-+ writel(cmd, sp->base + MTK_NOR_REG_CMD);
-+ ret = readl_poll_timeout(sp->base + MTK_NOR_REG_CMD, reg, !(reg & cmd),
-+ delay / 3, (delay + 1) * 200);
-+ if (ret < 0)
-+ dev_err(sp->dev, "command %u timeout.\n", cmd);
-+ return ret;
-+}
-+
-+static void mtk_nor_set_addr(struct mtk_nor *sp, const struct spi_mem_op *op)
-+{
-+ u32 addr = op->addr.val;
-+ int i;
-+
-+ for (i = 0; i < 3; i++) {
-+ writeb(addr & 0xff, sp->base + MTK_NOR_REG_RADR(i));
-+ addr >>= 8;
-+ }
-+ if (op->addr.nbytes == 4) {
-+ writeb(addr & 0xff, sp->base + MTK_NOR_REG_RADR3);
-+ mtk_nor_rmw(sp, MTK_NOR_REG_BUSCFG, MTK_NOR_4B_ADDR, 0);
-+ } else {
-+ mtk_nor_rmw(sp, MTK_NOR_REG_BUSCFG, 0, MTK_NOR_4B_ADDR);
-+ }
-+}
-+
-+static bool mtk_nor_match_read(const struct spi_mem_op *op)
-+{
-+ int dummy = 0;
-+
-+ if (op->dummy.buswidth)
-+ dummy = op->dummy.nbytes * BITS_PER_BYTE / op->dummy.buswidth;
-+
-+ if ((op->data.buswidth == 2) || (op->data.buswidth == 4)) {
-+ if (op->addr.buswidth == 1)
-+ return dummy == 8;
-+ else if (op->addr.buswidth == 2)
-+ return dummy == 4;
-+ else if (op->addr.buswidth == 4)
-+ return dummy == 6;
-+ } else if ((op->addr.buswidth == 1) && (op->data.buswidth == 1)) {
-+ if (op->cmd.opcode == 0x03)
-+ return dummy == 0;
-+ else if (op->cmd.opcode == 0x0b)
-+ return dummy == 8;
-+ }
-+ return false;
-+}
-+
-+static int mtk_nor_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
-+{
-+ size_t len;
-+
-+ if (!op->data.nbytes)
-+ return 0;
-+
-+ if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) {
-+ if ((op->data.dir == SPI_MEM_DATA_IN) &&
-+ mtk_nor_match_read(op)) {
-+ if ((op->addr.val & MTK_NOR_DMA_ALIGN_MASK) ||
-+ (op->data.nbytes < MTK_NOR_DMA_ALIGN))
-+ op->data.nbytes = 1;
-+ else if (!((ulong)(op->data.buf.in) &
-+ MTK_NOR_DMA_ALIGN_MASK))
-+ op->data.nbytes &= ~MTK_NOR_DMA_ALIGN_MASK;
-+ else if (op->data.nbytes > MTK_NOR_BOUNCE_BUF_SIZE)
-+ op->data.nbytes = MTK_NOR_BOUNCE_BUF_SIZE;
-+ return 0;
-+ } else if (op->data.dir == SPI_MEM_DATA_OUT) {
-+ if (op->data.nbytes >= MTK_NOR_PP_SIZE)
-+ op->data.nbytes = MTK_NOR_PP_SIZE;
-+ else
-+ op->data.nbytes = 1;
-+ return 0;
-+ }
-+ }
-+
-+ len = MTK_NOR_PRG_MAX_SIZE - sizeof(op->cmd.opcode) - op->addr.nbytes -
-+ op->dummy.nbytes;
-+ if (op->data.nbytes > len)
-+ op->data.nbytes = len;
-+
-+ return 0;
-+}
-+
-+static bool mtk_nor_supports_op(struct spi_mem *mem,
-+ const struct spi_mem_op *op)
-+{
-+ size_t len;
-+
-+ if (op->cmd.buswidth != 1)
-+ return false;
-+
-+ if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) {
-+ if ((op->data.dir == SPI_MEM_DATA_IN) && mtk_nor_match_read(op))
-+ return true;
-+ else if (op->data.dir == SPI_MEM_DATA_OUT)
-+ return (op->addr.buswidth == 1) &&
-+ (op->dummy.buswidth == 0) &&
-+ (op->data.buswidth == 1);
-+ }
-+ len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes;
-+ if ((len > MTK_NOR_PRG_MAX_SIZE) ||
-+ ((op->data.nbytes) && (len == MTK_NOR_PRG_MAX_SIZE)))
-+ return false;
-+ return true;
-+}
-+
-+static void mtk_nor_setup_bus(struct mtk_nor *sp, const struct spi_mem_op *op)
-+{
-+ u32 reg = 0;
-+
-+ if (op->addr.nbytes == 4)
-+ reg |= MTK_NOR_4B_ADDR;
-+
-+ if (op->data.buswidth == 4) {
-+ reg |= MTK_NOR_QUAD_READ;
-+ writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA(4));
-+ if (op->addr.buswidth == 4)
-+ reg |= MTK_NOR_QUAD_ADDR;
-+ } else if (op->data.buswidth == 2) {
-+ reg |= MTK_NOR_DUAL_READ;
-+ writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA(3));
-+ if (op->addr.buswidth == 2)
-+ reg |= MTK_NOR_DUAL_ADDR;
-+ } else {
-+ if (op->cmd.opcode == 0x0b)
-+ mtk_nor_rmw(sp, MTK_NOR_REG_CFG1, MTK_NOR_FAST_READ, 0);
-+ else
-+ mtk_nor_rmw(sp, MTK_NOR_REG_CFG1, 0, MTK_NOR_FAST_READ);
-+ }
-+ mtk_nor_rmw(sp, MTK_NOR_REG_BUSCFG, reg, MTK_NOR_BUS_MODE_MASK);
-+}
-+
-+static int mtk_nor_read_dma(struct mtk_nor *sp, u32 from, unsigned int length,
-+ u8 *buffer)
-+{
-+ int ret = 0;
-+ ulong delay;
-+ u32 reg;
-+ dma_addr_t dma_addr;
-+
-+ dma_addr = dma_map_single(sp->dev, buffer, length, DMA_FROM_DEVICE);
-+ if (dma_mapping_error(sp->dev, dma_addr)) {
-+ dev_err(sp->dev, "failed to map dma buffer.\n");
-+ return -EINVAL;
-+ }
-+
-+ writel(from, sp->base + MTK_NOR_REG_DMA_FADR);
-+ writel(dma_addr, sp->base + MTK_NOR_REG_DMA_DADR);
-+ writel(dma_addr + length, sp->base + MTK_NOR_REG_DMA_END_DADR);
-+
-+ if (sp->has_irq) {
-+ reinit_completion(&sp->op_done);
-+ mtk_nor_rmw(sp, MTK_NOR_REG_IRQ_EN, MTK_NOR_IRQ_DMA, 0);
-+ }
-+
-+ mtk_nor_rmw(sp, MTK_NOR_REG_DMA_CTL, MTK_NOR_DMA_START, 0);
-+
-+ delay = CLK_TO_US(sp, (length + 5) * BITS_PER_BYTE);
-+
-+ if (sp->has_irq) {
-+ if (!wait_for_completion_timeout(&sp->op_done,
-+ (delay + 1) * 100))
-+ ret = -ETIMEDOUT;
-+ } else {
-+ ret = readl_poll_timeout(sp->base + MTK_NOR_REG_DMA_CTL, reg,
-+ !(reg & MTK_NOR_DMA_START), delay / 3,
-+ (delay + 1) * 100);
-+ }
-+
-+ dma_unmap_single(sp->dev, dma_addr, length, DMA_FROM_DEVICE);
-+ if (ret < 0)
-+ dev_err(sp->dev, "dma read timeout.\n");
-+
-+ return ret;
-+}
-+
-+static int mtk_nor_read_bounce(struct mtk_nor *sp, u32 from,
-+ unsigned int length, u8 *buffer)
-+{
-+ unsigned int rdlen;
-+ int ret;
-+
-+ if (length & MTK_NOR_DMA_ALIGN_MASK)
-+ rdlen = (length + MTK_NOR_DMA_ALIGN) & ~MTK_NOR_DMA_ALIGN_MASK;
-+ else
-+ rdlen = length;
-+
-+ ret = mtk_nor_read_dma(sp, from, rdlen, sp->buffer);
-+ if (ret)
-+ return ret;
-+
-+ memcpy(buffer, sp->buffer, length);
-+ return 0;
-+}
-+
-+static int mtk_nor_read_pio(struct mtk_nor *sp, const struct spi_mem_op *op)
-+{
-+ u8 *buf = op->data.buf.in;
-+ int ret;
-+
-+ ret = mtk_nor_cmd_exec(sp, MTK_NOR_CMD_READ, 6 * BITS_PER_BYTE);
-+ if (!ret)
-+ buf[0] = readb(sp->base + MTK_NOR_REG_RDATA);
-+ return ret;
-+}
-+
-+static int mtk_nor_write_buffer_enable(struct mtk_nor *sp)
-+{
-+ int ret;
-+ u32 val;
-+
-+ if (sp->wbuf_en)
-+ return 0;
-+
-+ val = readl(sp->base + MTK_NOR_REG_CFG2);
-+ writel(val | MTK_NOR_WR_BUF_EN, sp->base + MTK_NOR_REG_CFG2);
-+ ret = readl_poll_timeout(sp->base + MTK_NOR_REG_CFG2, val,
-+ val & MTK_NOR_WR_BUF_EN, 0, 10000);
-+ if (!ret)
-+ sp->wbuf_en = true;
-+ return ret;
-+}
-+
-+static int mtk_nor_write_buffer_disable(struct mtk_nor *sp)
-+{
-+ int ret;
-+ u32 val;
-+
-+ if (!sp->wbuf_en)
-+ return 0;
-+ val = readl(sp->base + MTK_NOR_REG_CFG2);
-+ writel(val & ~MTK_NOR_WR_BUF_EN, sp->base + MTK_NOR_REG_CFG2);
-+ ret = readl_poll_timeout(sp->base + MTK_NOR_REG_CFG2, val,
-+ !(val & MTK_NOR_WR_BUF_EN), 0, 10000);
-+ if (!ret)
-+ sp->wbuf_en = false;
-+ return ret;
-+}
-+
-+static int mtk_nor_pp_buffered(struct mtk_nor *sp, const struct spi_mem_op *op)
-+{
-+ const u8 *buf = op->data.buf.out;
-+ u32 val;
-+ int ret, i;
-+
-+ ret = mtk_nor_write_buffer_enable(sp);
-+ if (ret < 0)
-+ return ret;
-+
-+ for (i = 0; i < op->data.nbytes; i += 4) {
-+ val = buf[i + 3] << 24 | buf[i + 2] << 16 | buf[i + 1] << 8 |
-+ buf[i];
-+ writel(val, sp->base + MTK_NOR_REG_PP_DATA);
-+ }
-+ return mtk_nor_cmd_exec(sp, MTK_NOR_CMD_WRITE,
-+ (op->data.nbytes + 5) * BITS_PER_BYTE);
-+}
-+
-+static int mtk_nor_pp_unbuffered(struct mtk_nor *sp,
-+ const struct spi_mem_op *op)
-+{
-+ const u8 *buf = op->data.buf.out;
-+ int ret;
-+
-+ ret = mtk_nor_write_buffer_disable(sp);
-+ if (ret < 0)
-+ return ret;
-+ writeb(buf[0], sp->base + MTK_NOR_REG_WDATA);
-+ return mtk_nor_cmd_exec(sp, MTK_NOR_CMD_WRITE, 6 * BITS_PER_BYTE);
-+}
-+
-+int mtk_nor_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
-+{
-+ struct mtk_nor *sp = spi_controller_get_devdata(mem->spi->master);
-+ int ret;
-+
-+ if ((op->data.nbytes == 0) ||
-+ ((op->addr.nbytes != 3) && (op->addr.nbytes != 4)))
-+ return -ENOTSUPP;
-+
-+ if (op->data.dir == SPI_MEM_DATA_OUT) {
-+ mtk_nor_set_addr(sp, op);
-+ writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA0);
-+ if (op->data.nbytes == MTK_NOR_PP_SIZE)
-+ return mtk_nor_pp_buffered(sp, op);
-+ return mtk_nor_pp_unbuffered(sp, op);
-+ }
-+
-+ if ((op->data.dir == SPI_MEM_DATA_IN) && mtk_nor_match_read(op)) {
-+ ret = mtk_nor_write_buffer_disable(sp);
-+ if (ret < 0)
-+ return ret;
-+ mtk_nor_setup_bus(sp, op);
-+ if (op->data.nbytes == 1) {
-+ mtk_nor_set_addr(sp, op);
-+ return mtk_nor_read_pio(sp, op);
-+ } else if (((ulong)(op->data.buf.in) &
-+ MTK_NOR_DMA_ALIGN_MASK)) {
-+ return mtk_nor_read_bounce(sp, op->addr.val,
-+ op->data.nbytes,
-+ op->data.buf.in);
-+ } else {
-+ return mtk_nor_read_dma(sp, op->addr.val,
-+ op->data.nbytes,
-+ op->data.buf.in);
-+ }
-+ }
-+
-+ return -ENOTSUPP;
-+}
-+
-+static int mtk_nor_setup(struct spi_device *spi)
-+{
-+ struct mtk_nor *sp = spi_controller_get_devdata(spi->master);
-+
-+ if (spi->max_speed_hz && (spi->max_speed_hz < sp->spi_freq)) {
-+ dev_err(&spi->dev, "spi clock should be %u Hz.\n",
-+ sp->spi_freq);
-+ return -EINVAL;
-+ }
-+ spi->max_speed_hz = sp->spi_freq;
-+
-+ return 0;
-+}
-+
-+static int mtk_nor_transfer_one_message(struct spi_controller *master,
-+ struct spi_message *m)
-+{
-+ struct mtk_nor *sp = spi_controller_get_devdata(master);
-+ struct spi_transfer *t = NULL;
-+ unsigned long trx_len = 0;
-+ int stat = 0;
-+ int reg_offset = MTK_NOR_REG_PRGDATA_MAX;
-+ void __iomem *reg;
-+ const u8 *txbuf;
-+ u8 *rxbuf;
-+ int i;
-+
-+ list_for_each_entry(t, &m->transfers, transfer_list) {
-+ txbuf = t->tx_buf;
-+ for (i = 0; i < t->len; i++, reg_offset--) {
-+ reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset);
-+ if (txbuf)
-+ writeb(txbuf[i], reg);
-+ else
-+ writeb(0, reg);
-+ }
-+ trx_len += t->len;
-+ }
-+
-+ writel(trx_len * BITS_PER_BYTE, sp->base + MTK_NOR_REG_PRG_CNT);
-+
-+ stat = mtk_nor_cmd_exec(sp, MTK_NOR_CMD_PROGRAM,
-+ trx_len * BITS_PER_BYTE);
-+ if (stat < 0)
-+ goto msg_done;
-+
-+ reg_offset = trx_len - 1;
-+ list_for_each_entry(t, &m->transfers, transfer_list) {
-+ rxbuf = t->rx_buf;
-+ for (i = 0; i < t->len; i++, reg_offset--) {
-+ reg = sp->base + MTK_NOR_REG_SHIFT(reg_offset);
-+ if (rxbuf)
-+ rxbuf[i] = readb(reg);
-+ }
-+ }
-+
-+ m->actual_length = trx_len;
-+msg_done:
-+ m->status = stat;
-+ spi_finalize_current_message(master);
-+
-+ return 0;
-+}
-+
-+static void mtk_nor_disable_clk(struct mtk_nor *sp)
-+{
-+ clk_disable_unprepare(sp->spi_clk);
-+ clk_disable_unprepare(sp->ctlr_clk);
-+}
-+
-+static int mtk_nor_enable_clk(struct mtk_nor *sp)
-+{
-+ int ret;
-+
-+ ret = clk_prepare_enable(sp->spi_clk);
-+ if (ret)
-+ return ret;
-+
-+ ret = clk_prepare_enable(sp->ctlr_clk);
-+ if (ret) {
-+ clk_disable_unprepare(sp->spi_clk);
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int mtk_nor_init(struct mtk_nor *sp)
-+{
-+ int ret;
-+
-+ ret = mtk_nor_enable_clk(sp);
-+ if (ret)
-+ return ret;
-+
-+ sp->spi_freq = clk_get_rate(sp->spi_clk);
-+
-+ writel(MTK_NOR_ENABLE_SF_CMD, sp->base + MTK_NOR_REG_WP);
-+ mtk_nor_rmw(sp, MTK_NOR_REG_CFG2, MTK_NOR_WR_CUSTOM_OP_EN, 0);
-+ mtk_nor_rmw(sp, MTK_NOR_REG_CFG3,
-+ MTK_NOR_DISABLE_WREN | MTK_NOR_DISABLE_SR_POLL, 0);
-+
-+ return ret;
-+}
-+
-+static irqreturn_t mtk_nor_irq_handler(int irq, void *data)
-+{
-+ struct mtk_nor *sp = data;
-+ u32 irq_status, irq_enabled;
-+
-+ irq_status = readl(sp->base + MTK_NOR_REG_IRQ_STAT);
-+ irq_enabled = readl(sp->base + MTK_NOR_REG_IRQ_EN);
-+ // write status back to clear interrupt
-+ writel(irq_status, sp->base + MTK_NOR_REG_IRQ_STAT);
-+
-+ if (!(irq_status & irq_enabled))
-+ return IRQ_NONE;
-+
-+ if (irq_status & MTK_NOR_IRQ_DMA) {
-+ complete(&sp->op_done);
-+ writel(0, sp->base + MTK_NOR_REG_IRQ_EN);
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static size_t mtk_max_msg_size(struct spi_device *spi)
-+{
-+ return MTK_NOR_PRG_MAX_SIZE;
-+}
-+
-+static const struct spi_controller_mem_ops mtk_nor_mem_ops = {
-+ .adjust_op_size = mtk_nor_adjust_op_size,
-+ .supports_op = mtk_nor_supports_op,
-+ .exec_op = mtk_nor_exec_op
-+};
-+
-+static const struct of_device_id mtk_nor_match[] = {
-+ { .compatible = "mediatek,mt8173-nor" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, mtk_nor_match);
-+
-+static int mtk_nor_probe(struct platform_device *pdev)
-+{
-+ struct spi_controller *ctlr;
-+ struct mtk_nor *sp;
-+ void __iomem *base;
-+ u8 *buffer;
-+ struct clk *spi_clk, *ctlr_clk;
-+ int ret, irq;
-+
-+ base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ spi_clk = devm_clk_get(&pdev->dev, "spi");
-+ if (IS_ERR(spi_clk))
-+ return PTR_ERR(spi_clk);
-+
-+ ctlr_clk = devm_clk_get(&pdev->dev, "sf");
-+ if (IS_ERR(ctlr_clk))
-+ return PTR_ERR(ctlr_clk);
-+
-+ buffer = devm_kmalloc(&pdev->dev,
-+ MTK_NOR_BOUNCE_BUF_SIZE + MTK_NOR_DMA_ALIGN,
-+ GFP_KERNEL);
-+ if (!buffer)
-+ return -ENOMEM;
-+
-+ if ((ulong)buffer & MTK_NOR_DMA_ALIGN_MASK)
-+ buffer = (u8 *)(((ulong)buffer + MTK_NOR_DMA_ALIGN) &
-+ ~MTK_NOR_DMA_ALIGN_MASK);
-+
-+ ctlr = spi_alloc_master(&pdev->dev, sizeof(*sp));
-+ if (!ctlr) {
-+ dev_err(&pdev->dev, "failed to allocate spi controller\n");
-+ return -ENOMEM;
-+ }
-+
-+ ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
-+ ctlr->dev.of_node = pdev->dev.of_node;
-+ ctlr->max_message_size = mtk_max_msg_size;
-+ ctlr->mem_ops = &mtk_nor_mem_ops;
-+ ctlr->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_DUAL | SPI_TX_QUAD;
-+ ctlr->num_chipselect = 1;
-+ ctlr->setup = mtk_nor_setup;
-+ ctlr->transfer_one_message = mtk_nor_transfer_one_message;
-+
-+ dev_set_drvdata(&pdev->dev, ctlr);
-+
-+ sp = spi_controller_get_devdata(ctlr);
-+ sp->base = base;
-+ sp->buffer = buffer;
-+ sp->has_irq = false;
-+ sp->wbuf_en = false;
-+ sp->ctlr = ctlr;
-+ sp->dev = &pdev->dev;
-+ sp->spi_clk = spi_clk;
-+ sp->ctlr_clk = ctlr_clk;
-+
-+ irq = platform_get_irq_optional(pdev, 0);
-+ if (irq < 0) {
-+ dev_warn(sp->dev, "IRQ not available.");
-+ } else {
-+ writel(MTK_NOR_IRQ_MASK, base + MTK_NOR_REG_IRQ_STAT);
-+ writel(0, base + MTK_NOR_REG_IRQ_EN);
-+ ret = devm_request_irq(sp->dev, irq, mtk_nor_irq_handler, 0,
-+ pdev->name, sp);
-+ if (ret < 0) {
-+ dev_warn(sp->dev, "failed to request IRQ.");
-+ } else {
-+ init_completion(&sp->op_done);
-+ sp->has_irq = true;
-+ }
-+ }
-+
-+ ret = mtk_nor_init(sp);
-+ if (ret < 0) {
-+ kfree(ctlr);
-+ return ret;
-+ }
-+
-+ dev_info(&pdev->dev, "spi frequency: %d Hz\n", sp->spi_freq);
-+
-+ return devm_spi_register_controller(&pdev->dev, ctlr);
-+}
-+
-+static int mtk_nor_remove(struct platform_device *pdev)
-+{
-+ struct spi_controller *ctlr;
-+ struct mtk_nor *sp;
-+
-+ ctlr = dev_get_drvdata(&pdev->dev);
-+ sp = spi_controller_get_devdata(ctlr);
-+
-+ mtk_nor_disable_clk(sp);
-+
-+ return 0;
-+}
-+
-+static struct platform_driver mtk_nor_driver = {
-+ .driver = {
-+ .name = DRIVER_NAME,
-+ .of_match_table = mtk_nor_match,
-+ },
-+ .probe = mtk_nor_probe,
-+ .remove = mtk_nor_remove,
-+};
-+
-+module_platform_driver(mtk_nor_driver);
-+
-+MODULE_DESCRIPTION("Mediatek SPI NOR controller driver");
-+MODULE_AUTHOR("Chuanhong Guo <gch981213@gmail.com>");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/target/linux/mediatek/patches-5.4/0003-switch-add-mt7531.patch b/target/linux/mediatek/patches-5.4/0003-switch-add-mt7531.patch
deleted file mode 100644
index 6fae99c1f4..0000000000
--- a/target/linux/mediatek/patches-5.4/0003-switch-add-mt7531.patch
+++ /dev/null
@@ -1,19 +0,0 @@
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -329,6 +329,8 @@ config RTL8367B_PHY
-
- endif # RTL8366_SMI
-
-+source "drivers/net/phy/mtk/mt753x/Kconfig"
-+
- comment "MII PHY device drivers"
-
- config SFP
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -109,3 +109,5 @@ obj-$(CONFIG_STE10XP) += ste10Xp.o
- obj-$(CONFIG_TERANETICS_PHY) += teranetics.o
- obj-$(CONFIG_VITESSE_PHY) += vitesse.o
- obj-$(CONFIG_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o
-+obj-$(CONFIG_MT753X_GSW) += mtk/mt753x/
-+
diff --git a/target/linux/mediatek/patches-5.4/0005-dts-mt7622-add-gsw.patch b/target/linux/mediatek/patches-5.4/0005-dts-mt7622-add-gsw.patch
deleted file mode 100644
index d40cbfb853..0000000000
--- a/target/linux/mediatek/patches-5.4/0005-dts-mt7622-add-gsw.patch
+++ /dev/null
@@ -1,258 +0,0 @@
---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-@@ -53,6 +53,13 @@
- };
- };
-
-+ gsw: gsw@0 {
-+ compatible = "mediatek,mt753x";
-+ mediatek,ethsys = <&ethsys>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -146,6 +153,36 @@
- };
- };
-
-+&gsw {
-+ mediatek,mdio = <&mdio>;
-+ mediatek,portmap = "wllll";
-+ mediatek,mdio_master_pinmux = <0>;
-+ reset-gpios = <&pio 54 0>;
-+ interrupt-parent = <&pio>;
-+ interrupts = <53 IRQ_TYPE_LEVEL_HIGH>;
-+ status = "okay";
-+
-+ port5: port@5 {
-+ compatible = "mediatek,mt753x-port";
-+ reg = <5>;
-+ phy-mode = "rgmii";
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
-+ port6: port@6 {
-+ compatible = "mediatek,mt753x-port";
-+ reg = <6>;
-+ phy-mode = "sgmii";
-+ fixed-link {
-+ speed = <2500>;
-+ full-duplex;
-+ };
-+ };
-+};
-+
- &i2c1 {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c1_pins>;
---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-@@ -1,7 +1,6 @@
- /*
-- * Copyright (c) 2017 MediaTek Inc.
-- * Author: Ming Huang <ming.huang@mediatek.com>
-- * Sean Wang <sean.wang@mediatek.com>
-+ * Copyright (c) 2018 MediaTek Inc.
-+ * Author: Ryder Lee <ryder.lee@mediatek.com>
- *
- * SPDX-License-Identifier: (GPL-2.0 OR MIT)
- */
-@@ -14,7 +13,7 @@
- #include "mt6380.dtsi"
-
- / {
-- model = "MediaTek MT7622 RFB1 board";
-+ model = "MT7622_MT7531 RFB";
- compatible = "mediatek,mt7622-rfb1", "mediatek,mt7622";
-
- aliases {
-@@ -23,7 +22,7 @@
-
- chosen {
- stdout-path = "serial0:115200n8";
-- bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512";
-+ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512";
- };
-
- cpus {
-@@ -40,23 +39,36 @@
-
- gpio-keys {
- compatible = "gpio-keys";
-- poll-interval = <100>;
-
- factory {
- label = "factory";
- linux,code = <BTN_0>;
-- gpios = <&pio 0 0>;
-+ gpios = <&pio 0 GPIO_ACTIVE_LOW>;
- };
-
- wps {
- label = "wps";
- linux,code = <KEY_WPS_BUTTON>;
-- gpios = <&pio 102 0>;
-+ gpios = <&pio 102 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ green {
-+ label = "bpi-r64:pio:green";
-+ gpios = <&pio 89 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ red {
-+ label = "bpi-r64:pio:red";
-+ gpios = <&pio 88 GPIO_ACTIVE_HIGH>;
- };
- };
-
- memory {
-- reg = <0 0x40000000 0 0x20000000>;
-+ reg = <0 0x40000000 0 0x40000000>;
- };
-
- reg_1p8v: regulator-1p8v {
-@@ -101,23 +113,82 @@
- };
-
- &eth {
-- pinctrl-names = "default";
-- pinctrl-0 = <&eth_pins>;
- status = "okay";
-+ gmac0: mac@0 {
-+ compatible = "mediatek,eth-mac";
-+ reg = <0>;
-+ phy-mode = "2500base-x";
-+
-+ fixed-link {
-+ speed = <2500>;
-+ full-duplex;
-+ pause;
-+ };
-+ };
-
- gmac1: mac@1 {
- compatible = "mediatek,eth-mac";
- reg = <1>;
-- phy-handle = <&phy5>;
-+ phy-mode = "rgmii";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ pause;
-+ };
- };
-
-- mdio-bus {
-+ mdio: mdio-bus {
- #address-cells = <1>;
- #size-cells = <0>;
-
-- phy5: ethernet-phy@5 {
-- reg = <5>;
-- phy-mode = "sgmii";
-+ switch@0 {
-+ compatible = "mediatek,mt7531";
-+ reg = <0>;
-+ reset-gpios = <&pio 54 0>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ port@6 {
-+ reg = <6>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+ phy-mode = "2500base-x";
-+
-+ fixed-link {
-+ speed = <2500>;
-+ full-duplex;
-+ pause;
-+ };
-+ };
-+ };
- };
- };
- };
-@@ -185,15 +256,28 @@
-
- &pcie {
- pinctrl-names = "default";
-- pinctrl-0 = <&pcie0_pins>;
-+ pinctrl-0 = <&pcie0_pins>, <&pcie1_pins>;
- status = "okay";
-
- pcie@0,0 {
- status = "okay";
- };
-+
-+ pcie@1,0 {
-+ status = "okay";
-+ };
- };
-
- &pio {
-+ /* Attention: GPIO 90 is used to switch between PCIe@1,0 and
-+ * SATA functions. i.e. output-high: PCIe, output-low: SATA
-+ */
-+ asm_sel {
-+ gpio-hog;
-+ gpios = <90 GPIO_ACTIVE_HIGH>;
-+ output-high;
-+ };
-+
- /* eMMC is shared pin with parallel NAND */
- emmc_pins_default: emmc-pins-default {
- mux {
-@@ -460,11 +544,11 @@
- };
-
- &sata {
-- status = "okay";
-+ status = "disable";
- };
-
- &sata_phy {
-- status = "okay";
-+ status = "disable";
- };
-
- &spi0 {
diff --git a/target/linux/mediatek/patches-5.4/0005-dts-mt7629-add-gsw.patch b/target/linux/mediatek/patches-5.4/0005-dts-mt7629-add-gsw.patch
deleted file mode 100644
index 4028bad4df..0000000000
--- a/target/linux/mediatek/patches-5.4/0005-dts-mt7629-add-gsw.patch
+++ /dev/null
@@ -1,90 +0,0 @@
---- a/arch/arm/boot/dts/mt7629-rfb.dts
-+++ b/arch/arm/boot/dts/mt7629-rfb.dts
-@@ -18,6 +18,7 @@
-
- chosen {
- stdout-path = "serial0:115200n8";
-+ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n8";
- };
-
- gpio-keys {
-@@ -36,6 +37,13 @@
- };
- };
-
-+ gsw: gsw@0 {
-+ compatible = "mediatek,mt753x";
-+ mediatek,ethsys = <&ethsys>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+
- memory@40000000 {
- device_type = "memory";
- reg = <0x40000000 0x10000000>;
-@@ -70,6 +78,10 @@
- compatible = "mediatek,eth-mac";
- reg = <0>;
- phy-mode = "2500base-x";
-+
-+ nvmem-cells = <&macaddr_factory_2a>;
-+ nvmem-cell-names = "mac-address";
-+
- fixed-link {
- speed = <2500>;
- full-duplex;
-@@ -82,6 +94,9 @@
- reg = <1>;
- phy-mode = "gmii";
- phy-handle = <&phy0>;
-+
-+ nvmem-cells = <&macaddr_factory_24>;
-+ nvmem-cell-names = "mac-address";
- };
-
- mdio: mdio-bus {
-@@ -94,6 +109,26 @@
- };
- };
-
-+&gsw {
-+ mediatek,mdio = <&mdio>;
-+ mediatek,portmap = "llllw";
-+ mediatek,mdio_master_pinmux = <0>;
-+ reset-gpios = <&pio 28 0>;
-+ interrupt-parent = <&pio>;
-+ interrupts = <6 IRQ_TYPE_LEVEL_HIGH>;
-+ status = "okay";
-+
-+ port6: port@6 {
-+ compatible = "mediatek,mt753x-port";
-+ reg = <6>;
-+ phy-mode = "sgmii";
-+ fixed-link {
-+ speed = <2500>;
-+ full-duplex;
-+ };
-+ };
-+};
-+
- &i2c {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c_pins>;
-@@ -272,3 +307,17 @@
- pinctrl-0 = <&watchdog_pins>;
- status = "okay";
- };
-+
-+&factory {
-+ compatible = "nvmem-cells";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ macaddr_factory_24: macaddr@24 {
-+ reg = <0x24 0x6>;
-+ };
-+
-+ macaddr_factory_2a: macaddr@2a {
-+ reg = <0x2a 0x6>;
-+ };
-+};
diff --git a/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi2-console.patch b/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi2-console.patch
deleted file mode 100644
index b7251177f2..0000000000
--- a/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi2-console.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
-+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
-@@ -19,6 +19,7 @@
-
- chosen {
- stdout-path = "serial2:115200n8";
-+ bootargs = "console=ttyS2,115200n8";
- };
-
- cpus {
diff --git a/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi64-console.patch b/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi64-console.patch
deleted file mode 100644
index 07a2eae245..0000000000
--- a/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi64-console.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-@@ -22,7 +22,7 @@
-
- chosen {
- stdout-path = "serial0:115200n8";
-- bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512";
-+ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512";
- };
-
- cpus {
diff --git a/target/linux/mediatek/patches-5.4/0010-dts-mt7629-rfb-fix-firmware-partition.patch b/target/linux/mediatek/patches-5.4/0010-dts-mt7629-rfb-fix-firmware-partition.patch
deleted file mode 100644
index 2c48e5706f..0000000000
--- a/target/linux/mediatek/patches-5.4/0010-dts-mt7629-rfb-fix-firmware-partition.patch
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/arch/arm/boot/dts/mt7629-rfb.dts
-+++ b/arch/arm/boot/dts/mt7629-rfb.dts
-@@ -168,8 +168,9 @@
- };
-
- partition@b0000 {
-- label = "kernel";
-+ label = "firmware";
- reg = <0xb0000 0xb50000>;
-+ compatible = "denx,fit";
- };
- };
- };
diff --git a/target/linux/mediatek/patches-5.4/0226-phy-phy-mtk-tphy-Add-hifsys-support.patch b/target/linux/mediatek/patches-5.4/0226-phy-phy-mtk-tphy-Add-hifsys-support.patch
deleted file mode 100644
index f2647e8ffe..0000000000
--- a/target/linux/mediatek/patches-5.4/0226-phy-phy-mtk-tphy-Add-hifsys-support.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-From 28f9a5e2a3f5441ab5594669ed82da11e32277a9 Mon Sep 17 00:00:00 2001
-From: Kristian Evensen <kristian.evensen@gmail.com>
-Date: Mon, 30 Apr 2018 14:38:01 +0200
-Subject: [PATCH] phy: phy-mtk-tphy: Add hifsys-support
-
----
- drivers/phy/mediatek/phy-mtk-tphy.c | 20 ++++++++++++++++++++
- 1 file changed, 20 insertions(+)
-
---- a/drivers/phy/mediatek/phy-mtk-tphy.c
-+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
-@@ -15,6 +15,8 @@
- #include <linux/of_device.h>
- #include <linux/phy/phy.h>
- #include <linux/platform_device.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/regmap.h>
-
- /* version V1 sub-banks offset base address */
- /* banks shared by multiple phys */
-@@ -263,6 +265,9 @@
- #define RG_CDR_BIRLTD0_GEN3_MSK GENMASK(4, 0)
- #define RG_CDR_BIRLTD0_GEN3_VAL(x) (0x1f & (x))
-
-+#define HIF_SYSCFG1 0x14
-+#define HIF_SYSCFG1_PHY2_MASK (0x3 << 20)
-+
- enum mtk_phy_version {
- MTK_PHY_V1 = 1,
- MTK_PHY_V2,
-@@ -310,6 +315,7 @@ struct mtk_tphy {
- struct clk *u3phya_ref; /* reference clock of usb3 anolog phy */
- const struct mtk_phy_pdata *pdata;
- struct mtk_phy_instance **phys;
-+ struct regmap *hif;
- int nphys;
- int src_ref_clk; /* MHZ, reference clock for slew rate calibrate */
- int src_coef; /* coefficient for slew rate calibrate */
-@@ -629,6 +635,10 @@ static void pcie_phy_instance_init(struc
- if (tphy->pdata->version != MTK_PHY_V1)
- return;
-
-+ if (tphy->hif)
-+ regmap_update_bits(tphy->hif, HIF_SYSCFG1,
-+ HIF_SYSCFG1_PHY2_MASK, 0);
-+
- tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG0);
- tmp &= ~(P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H);
- tmp |= P3A_RG_XTAL_EXT_PE1H_VAL(0x2) | P3A_RG_XTAL_EXT_PE2H_VAL(0x2);
-@@ -1114,6 +1124,16 @@ static int mtk_tphy_probe(struct platfor
- &tphy->src_ref_clk);
- device_property_read_u32(dev, "mediatek,src-coef", &tphy->src_coef);
-
-+ if (of_find_property(np, "mediatek,phy-switch", NULL)) {
-+ tphy->hif = syscon_regmap_lookup_by_phandle(np,
-+ "mediatek,phy-switch");
-+ if (IS_ERR(tphy->hif)) {
-+ dev_err(&pdev->dev,
-+ "missing \"mediatek,phy-switch\" phandle\n");
-+ return PTR_ERR(tphy->hif);
-+ }
-+ }
-+
- port = 0;
- for_each_child_of_node(np, child_np) {
- struct mtk_phy_instance *instance;
diff --git a/target/linux/mediatek/patches-5.4/0301-mtd-mtk-ecc-move-mtk-ecc-header-file-to-include-mtd.patch b/target/linux/mediatek/patches-5.4/0301-mtd-mtk-ecc-move-mtk-ecc-header-file-to-include-mtd.patch
deleted file mode 100644
index d9ab339fa8..0000000000
--- a/target/linux/mediatek/patches-5.4/0301-mtd-mtk-ecc-move-mtk-ecc-header-file-to-include-mtd.patch
+++ /dev/null
@@ -1,139 +0,0 @@
-From a2479dc254ebe31c84fbcfda73f35e2321576494 Mon Sep 17 00:00:00 2001
-From: Xiangsheng Hou <xiangsheng.hou@mediatek.com>
-Date: Tue, 19 Mar 2019 13:57:38 +0800
-Subject: [PATCH 1/6] mtd: mtk ecc: move mtk ecc header file to include/mtd
-
-Change-Id: I8dc1d30e21b40d68ef5efd9587012f82970156a5
-Signed-off-by: Xiangsheng Hou <xiangsheng.hou@mediatek.com>
----
- drivers/mtd/nand/raw/mtk_ecc.c | 3 +--
- drivers/mtd/nand/raw/mtk_nand.c | 2 +-
- {drivers/mtd/nand/raw => include/linux/mtd}/mtk_ecc.h | 0
- 3 files changed, 2 insertions(+), 3 deletions(-)
- rename {drivers/mtd/nand/raw => include/linux/mtd}/mtk_ecc.h (100%)
-
---- a/drivers/mtd/nand/raw/mtk_ecc.c
-+++ b/drivers/mtd/nand/raw/mtk_ecc.c
-@@ -15,8 +15,7 @@
- #include <linux/of.h>
- #include <linux/of_platform.h>
- #include <linux/mutex.h>
--
--#include "mtk_ecc.h"
-+#include <linux/mtd/mtk_ecc.h>
-
- #define ECC_IDLE_MASK BIT(0)
- #define ECC_IRQ_EN BIT(0)
---- a/drivers/mtd/nand/raw/mtk_nand.c
-+++ b/drivers/mtd/nand/raw/mtk_nand.c
-@@ -17,7 +17,7 @@
- #include <linux/iopoll.h>
- #include <linux/of.h>
- #include <linux/of_device.h>
--#include "mtk_ecc.h"
-+#include <linux/mtd/mtk_ecc.h>
-
- /* NAND controller register definition */
- #define NFI_CNFG (0x00)
---- /dev/null
-+++ b/include/linux/mtd/mtk_ecc.h
-@@ -0,0 +1,49 @@
-+/*
-+ * MTK SDG1 ECC controller
-+ *
-+ * Copyright (c) 2016 Mediatek
-+ * Authors: Xiaolei Li <xiaolei.li@mediatek.com>
-+ * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ */
-+
-+#ifndef __DRIVERS_MTD_NAND_MTK_ECC_H__
-+#define __DRIVERS_MTD_NAND_MTK_ECC_H__
-+
-+#include <linux/types.h>
-+
-+enum mtk_ecc_mode {ECC_DMA_MODE = 0, ECC_NFI_MODE = 1};
-+enum mtk_ecc_operation {ECC_ENCODE, ECC_DECODE};
-+
-+struct device_node;
-+struct mtk_ecc;
-+
-+struct mtk_ecc_stats {
-+ u32 corrected;
-+ u32 bitflips;
-+ u32 failed;
-+};
-+
-+struct mtk_ecc_config {
-+ enum mtk_ecc_operation op;
-+ enum mtk_ecc_mode mode;
-+ dma_addr_t addr;
-+ u32 strength;
-+ u32 sectors;
-+ u32 len;
-+};
-+
-+int mtk_ecc_encode(struct mtk_ecc *, struct mtk_ecc_config *, u8 *, u32);
-+void mtk_ecc_get_stats(struct mtk_ecc *, struct mtk_ecc_stats *, int);
-+int mtk_ecc_wait_done(struct mtk_ecc *, enum mtk_ecc_operation);
-+int mtk_ecc_enable(struct mtk_ecc *, struct mtk_ecc_config *);
-+void mtk_ecc_disable(struct mtk_ecc *);
-+void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p);
-+unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc);
-+
-+struct mtk_ecc *of_mtk_ecc_get(struct device_node *);
-+void mtk_ecc_release(struct mtk_ecc *);
-+
-+#endif
---- a/drivers/mtd/nand/raw/mtk_ecc.h
-+++ /dev/null
-@@ -1,47 +0,0 @@
--/* SPDX-License-Identifier: GPL-2.0 OR MIT */
--/*
-- * MTK SDG1 ECC controller
-- *
-- * Copyright (c) 2016 Mediatek
-- * Authors: Xiaolei Li <xiaolei.li@mediatek.com>
-- * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
-- */
--
--#ifndef __DRIVERS_MTD_NAND_MTK_ECC_H__
--#define __DRIVERS_MTD_NAND_MTK_ECC_H__
--
--#include <linux/types.h>
--
--enum mtk_ecc_mode {ECC_DMA_MODE = 0, ECC_NFI_MODE = 1};
--enum mtk_ecc_operation {ECC_ENCODE, ECC_DECODE};
--
--struct device_node;
--struct mtk_ecc;
--
--struct mtk_ecc_stats {
-- u32 corrected;
-- u32 bitflips;
-- u32 failed;
--};
--
--struct mtk_ecc_config {
-- enum mtk_ecc_operation op;
-- enum mtk_ecc_mode mode;
-- dma_addr_t addr;
-- u32 strength;
-- u32 sectors;
-- u32 len;
--};
--
--int mtk_ecc_encode(struct mtk_ecc *, struct mtk_ecc_config *, u8 *, u32);
--void mtk_ecc_get_stats(struct mtk_ecc *, struct mtk_ecc_stats *, int);
--int mtk_ecc_wait_done(struct mtk_ecc *, enum mtk_ecc_operation);
--int mtk_ecc_enable(struct mtk_ecc *, struct mtk_ecc_config *);
--void mtk_ecc_disable(struct mtk_ecc *);
--void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p);
--unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc);
--
--struct mtk_ecc *of_mtk_ecc_get(struct device_node *);
--void mtk_ecc_release(struct mtk_ecc *);
--
--#endif
diff --git a/target/linux/mediatek/patches-5.4/0303-mtd-spinand-disable-on-die-ECC.patch b/target/linux/mediatek/patches-5.4/0303-mtd-spinand-disable-on-die-ECC.patch
deleted file mode 100644
index 5c18ea0f74..0000000000
--- a/target/linux/mediatek/patches-5.4/0303-mtd-spinand-disable-on-die-ECC.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From b341f120cfc9ca1dfd48364b7f36ac2c1fbdea43 Mon Sep 17 00:00:00 2001
-From: Xiangsheng Hou <xiangsheng.hou@mediatek.com>
-Date: Wed, 3 Apr 2019 16:30:01 +0800
-Subject: [PATCH 3/6] mtd: spinand: disable on-die ECC
-
-Change-Id: I9745adaed5295202fabbe8ab8947885c57a5b847
-Signed-off-by: Xiangsheng Hou <xiangsheng.hou@mediatek.com>
----
- drivers/mtd/nand/spi/core.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -491,7 +491,7 @@ static int spinand_mtd_read(struct mtd_i
- int ret = 0;
-
- if (ops->mode != MTD_OPS_RAW && spinand->eccinfo.ooblayout)
-- enable_ecc = true;
-+ enable_ecc = false;
-
- mutex_lock(&spinand->lock);
-
-@@ -539,7 +539,7 @@ static int spinand_mtd_write(struct mtd_
- int ret = 0;
-
- if (ops->mode != MTD_OPS_RAW && mtd->ooblayout)
-- enable_ecc = true;
-+ enable_ecc = false;
-
- mutex_lock(&spinand->lock);
-
diff --git a/target/linux/mediatek/patches-5.4/0306-spi-spi-mem-MediaTek-Add-SPI-NAND-Flash-interface-dr.patch b/target/linux/mediatek/patches-5.4/0306-spi-spi-mem-MediaTek-Add-SPI-NAND-Flash-interface-dr.patch
deleted file mode 100644
index b3672e5b15..0000000000
--- a/target/linux/mediatek/patches-5.4/0306-spi-spi-mem-MediaTek-Add-SPI-NAND-Flash-interface-dr.patch
+++ /dev/null
@@ -1,1246 +0,0 @@
-From 1ecb38eabd90efe93957d0a822a167560c39308a Mon Sep 17 00:00:00 2001
-From: Xiangsheng Hou <xiangsheng.hou@mediatek.com>
-Date: Wed, 20 Mar 2019 16:19:51 +0800
-Subject: [PATCH 6/6] spi: spi-mem: MediaTek: Add SPI NAND Flash interface
- driver for MediaTek MT7622
-
-Change-Id: I3e78406bb9b46b0049d3988a5c71c7069e4f809c
-Signed-off-by: Xiangsheng Hou <xiangsheng.hou@mediatek.com>
----
- drivers/spi/Kconfig | 9 +
- drivers/spi/Makefile | 1 +
- drivers/spi/spi-mtk-snfi.c | 1183 ++++++++++++++++++++++++++++++++++++
- 3 files changed, 1193 insertions(+)
- create mode 100644 drivers/spi/spi-mtk-snfi.c
-
---- a/drivers/spi/Makefile
-+++ b/drivers/spi/Makefile
-@@ -60,6 +60,7 @@ obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mp
- obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o
- obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o
- obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o
-+obj-$(CONFIG_SPI_MTK_SNFI) += spi-mtk-snfi.o
- obj-$(CONFIG_SPI_MT7621) += spi-mt7621.o
- obj-$(CONFIG_SPI_MTK_NOR) += spi-mtk-nor.o
- obj-$(CONFIG_SPI_MXIC) += spi-mxic.o
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -427,6 +427,15 @@ config SPI_MT65XX
- say Y or M here.If you are not sure, say N.
- SPI drivers for Mediatek MT65XX and MT81XX series ARM SoCs.
-
-+config SPI_MTK_SNFI
-+ tristate "MediaTek SPI NAND interface"
-+ select MTD_SPI_NAND
-+ help
-+ This selects the SPI NAND FLASH interface(SNFI),
-+ which could be found on MediaTek Soc.
-+ Say Y or M here.If you are not sure, say N.
-+ Note Parallel Nand and SPI NAND is alternative on MediaTek SoCs.
-+
- config SPI_MT7621
- tristate "MediaTek MT7621 SPI Controller"
- depends on RALINK || COMPILE_TEST
---- /dev/null
-+++ b/drivers/spi/spi-mtk-snfi.c
-@@ -0,0 +1,1200 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Driver for MediaTek SPI Nand interface
-+ *
-+ * Copyright (C) 2018 MediaTek Inc.
-+ * Authors: Xiangsheng Hou <xiangsheng.hou@mediatek.com>
-+ *
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/interrupt.h>
-+#include <linux/iopoll.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/mtk_ecc.h>
-+#include <linux/mtd/spinand.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/spi/spi.h>
-+#include <linux/spi/spi-mem.h>
-+
-+/* NAND controller register definition */
-+/* NFI control */
-+#define NFI_CNFG 0x00
-+#define CNFG_DMA BIT(0)
-+#define CNFG_READ_EN BIT(1)
-+#define CNFG_DMA_BURST_EN BIT(2)
-+#define CNFG_BYTE_RW BIT(6)
-+#define CNFG_HW_ECC_EN BIT(8)
-+#define CNFG_AUTO_FMT_EN BIT(9)
-+#define CNFG_OP_PROGRAM (3UL << 12)
-+#define CNFG_OP_CUST (6UL << 12)
-+#define NFI_PAGEFMT 0x04
-+#define PAGEFMT_512 0
-+#define PAGEFMT_2K 1
-+#define PAGEFMT_4K 2
-+#define PAGEFMT_FDM_SHIFT 8
-+#define PAGEFMT_FDM_ECC_SHIFT 12
-+#define NFI_CON 0x08
-+#define CON_FIFO_FLUSH BIT(0)
-+#define CON_NFI_RST BIT(1)
-+#define CON_BRD BIT(8)
-+#define CON_BWR BIT(9)
-+#define CON_SEC_SHIFT 12
-+#define NFI_INTR_EN 0x10
-+#define INTR_AHB_DONE_EN BIT(6)
-+#define NFI_INTR_STA 0x14
-+#define NFI_CMD 0x20
-+#define NFI_STA 0x60
-+#define STA_EMP_PAGE BIT(12)
-+#define NAND_FSM_MASK (0x1f << 24)
-+#define NFI_FSM_MASK (0xf << 16)
-+#define NFI_ADDRCNTR 0x70
-+#define CNTR_MASK GENMASK(16, 12)
-+#define ADDRCNTR_SEC_SHIFT 12
-+#define ADDRCNTR_SEC(val) \
-+ (((val) & CNTR_MASK) >> ADDRCNTR_SEC_SHIFT)
-+#define NFI_STRADDR 0x80
-+#define NFI_BYTELEN 0x84
-+#define NFI_CSEL 0x90
-+#define NFI_FDML(x) (0xa0 + (x) * sizeof(u32) * 2)
-+#define NFI_FDMM(x) (0xa4 + (x) * sizeof(u32) * 2)
-+#define NFI_MASTER_STA 0x224
-+#define MASTER_STA_MASK 0x0fff
-+/* NFI_SPI control */
-+#define SNFI_MAC_OUTL 0x504
-+#define SNFI_MAC_INL 0x508
-+#define SNFI_RD_CTL2 0x510
-+#define RD_CMD_MASK 0x00ff
-+#define RD_DUMMY_SHIFT 8
-+#define SNFI_RD_CTL3 0x514
-+#define RD_ADDR_MASK 0xffff
-+#define SNFI_MISC_CTL 0x538
-+#define RD_MODE_X2 BIT(16)
-+#define RD_MODE_X4 (2UL << 16)
-+#define RD_QDUAL_IO (4UL << 16)
-+#define RD_MODE_MASK (7UL << 16)
-+#define RD_CUSTOM_EN BIT(6)
-+#define WR_CUSTOM_EN BIT(7)
-+#define WR_X4_EN BIT(20)
-+#define SW_RST BIT(28)
-+#define SNFI_MISC_CTL2 0x53c
-+#define WR_LEN_SHIFT 16
-+#define SNFI_PG_CTL1 0x524
-+#define WR_LOAD_CMD_SHIFT 8
-+#define SNFI_PG_CTL2 0x528
-+#define WR_LOAD_ADDR_MASK 0xffff
-+#define SNFI_MAC_CTL 0x500
-+#define MAC_WIP BIT(0)
-+#define MAC_WIP_READY BIT(1)
-+#define MAC_TRIG BIT(2)
-+#define MAC_EN BIT(3)
-+#define MAC_SIO_SEL BIT(4)
-+#define SNFI_STA_CTL1 0x550
-+#define SPI_STATE_IDLE 0xf
-+#define SNFI_CNFG 0x55c
-+#define SNFI_MODE_EN BIT(0)
-+#define SNFI_GPRAM_DATA 0x800
-+#define SNFI_GPRAM_MAX_LEN 16
-+
-+/* Dummy command trigger NFI to spi mode */
-+#define NAND_CMD_DUMMYREAD 0x00
-+#define NAND_CMD_DUMMYPROG 0x80
-+
-+#define MTK_TIMEOUT 500000
-+#define MTK_RESET_TIMEOUT 1000000
-+#define MTK_SNFC_MIN_SPARE 16
-+#define KB(x) ((x) * 1024UL)
-+
-+/*
-+ * supported spare size of each IP.
-+ * order should be the same with the spare size bitfiled defination of
-+ * register NFI_PAGEFMT.
-+ */
-+static const u8 spare_size_mt7622[] = {
-+ 16, 26, 27, 28
-+};
-+
-+struct mtk_snfi_caps {
-+ const u8 *spare_size;
-+ u8 num_spare_size;
-+ u32 nand_sec_size;
-+ u8 nand_fdm_size;
-+ u8 nand_fdm_ecc_size;
-+ u8 ecc_parity_bits;
-+ u8 pageformat_spare_shift;
-+ u8 bad_mark_swap;
-+};
-+
-+struct mtk_snfi_bad_mark_ctl {
-+ void (*bm_swap)(struct spi_mem *mem, u8 *buf, int raw);
-+ u32 sec;
-+ u32 pos;
-+};
-+
-+struct mtk_snfi_nand_chip {
-+ struct mtk_snfi_bad_mark_ctl bad_mark;
-+ u32 spare_per_sector;
-+};
-+
-+struct mtk_snfi_clk {
-+ struct clk *nfi_clk;
-+ struct clk *spi_clk;
-+};
-+
-+struct mtk_snfi {
-+ const struct mtk_snfi_caps *caps;
-+ struct mtk_snfi_nand_chip snfi_nand;
-+ struct mtk_snfi_clk clk;
-+ struct mtk_ecc_config ecc_cfg;
-+ struct mtk_ecc *ecc;
-+ struct completion done;
-+ struct device *dev;
-+
-+ void __iomem *regs;
-+
-+ u8 *buffer;
-+};
-+
-+static inline u8 *oob_ptr(struct spi_mem *mem, int i)
-+{
-+ struct spinand_device *spinand = spi_mem_get_drvdata(mem);
-+ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master);
-+ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand;
-+ u8 *poi;
-+
-+ /* map the sector's FDM data to free oob:
-+ * the beginning of the oob area stores the FDM data of bad mark
-+ */
-+
-+ if (i < snfi_nand->bad_mark.sec)
-+ poi = spinand->oobbuf + (i + 1) * snfi->caps->nand_fdm_size;
-+ else if (i == snfi_nand->bad_mark.sec)
-+ poi = spinand->oobbuf;
-+ else
-+ poi = spinand->oobbuf + i * snfi->caps->nand_fdm_size;
-+
-+ return poi;
-+}
-+
-+static inline int mtk_data_len(struct spi_mem *mem)
-+{
-+ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master);
-+ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand;
-+
-+ return snfi->caps->nand_sec_size + snfi_nand->spare_per_sector;
-+}
-+
-+static inline u8 *mtk_oob_ptr(struct spi_mem *mem,
-+ const u8 *p, int i)
-+{
-+ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master);
-+
-+ return (u8 *)p + i * mtk_data_len(mem) + snfi->caps->nand_sec_size;
-+}
-+
-+static void mtk_snfi_bad_mark_swap(struct spi_mem *mem,
-+ u8 *buf, int raw)
-+{
-+ struct spinand_device *spinand = spi_mem_get_drvdata(mem);
-+ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master);
-+ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand;
-+ u32 bad_pos = snfi_nand->bad_mark.pos;
-+
-+ if (raw)
-+ bad_pos += snfi_nand->bad_mark.sec * mtk_data_len(mem);
-+ else
-+ bad_pos += snfi_nand->bad_mark.sec * snfi->caps->nand_sec_size;
-+
-+ swap(spinand->oobbuf[0], buf[bad_pos]);
-+}
-+
-+static void mtk_snfi_set_bad_mark_ctl(struct mtk_snfi_bad_mark_ctl *bm_ctl,
-+ struct spi_mem *mem)
-+{
-+ struct spinand_device *spinand = spi_mem_get_drvdata(mem);
-+ struct mtd_info *mtd = spinand_to_mtd(spinand);
-+
-+ bm_ctl->bm_swap = mtk_snfi_bad_mark_swap;
-+ bm_ctl->sec = mtd->writesize / mtk_data_len(mem);
-+ bm_ctl->pos = mtd->writesize % mtk_data_len(mem);
-+}
-+
-+static void mtk_snfi_mac_enable(struct mtk_snfi *snfi)
-+{
-+ u32 mac;
-+
-+ mac = readl(snfi->regs + SNFI_MAC_CTL);
-+ mac &= ~MAC_SIO_SEL;
-+ mac |= MAC_EN;
-+
-+ writel(mac, snfi->regs + SNFI_MAC_CTL);
-+}
-+
-+static int mtk_snfi_mac_trigger(struct mtk_snfi *snfi)
-+{
-+ u32 mac, reg;
-+ int ret = 0;
-+
-+ mac = readl(snfi->regs + SNFI_MAC_CTL);
-+ mac |= MAC_TRIG;
-+ writel(mac, snfi->regs + SNFI_MAC_CTL);
-+
-+ ret = readl_poll_timeout_atomic(snfi->regs + SNFI_MAC_CTL, reg,
-+ reg & MAC_WIP_READY, 10,
-+ MTK_TIMEOUT);
-+ if (ret < 0) {
-+ dev_err(snfi->dev, "polling wip ready for read timeout\n");
-+ return -EIO;
-+ }
-+
-+ ret = readl_poll_timeout_atomic(snfi->regs + SNFI_MAC_CTL, reg,
-+ !(reg & MAC_WIP), 10,
-+ MTK_TIMEOUT);
-+ if (ret < 0) {
-+ dev_err(snfi->dev, "polling flash update timeout\n");
-+ return -EIO;
-+ }
-+
-+ return ret;
-+}
-+
-+static void mtk_snfi_mac_leave(struct mtk_snfi *snfi)
-+{
-+ u32 mac;
-+
-+ mac = readl(snfi->regs + SNFI_MAC_CTL);
-+ mac &= ~(MAC_TRIG | MAC_EN | MAC_SIO_SEL);
-+ writel(mac, snfi->regs + SNFI_MAC_CTL);
-+}
-+
-+static int mtk_snfi_mac_op(struct mtk_snfi *snfi)
-+{
-+ int ret = 0;
-+
-+ mtk_snfi_mac_enable(snfi);
-+
-+ ret = mtk_snfi_mac_trigger(snfi);
-+ if (ret)
-+ return ret;
-+
-+ mtk_snfi_mac_leave(snfi);
-+
-+ return ret;
-+}
-+
-+static irqreturn_t mtk_snfi_irq(int irq, void *id)
-+{
-+ struct mtk_snfi *snfi = id;
-+ u16 sta, ien;
-+
-+ sta = readw(snfi->regs + NFI_INTR_STA);
-+ ien = readw(snfi->regs + NFI_INTR_EN);
-+
-+ if (!(sta & ien))
-+ return IRQ_NONE;
-+
-+ writew(~sta & ien, snfi->regs + NFI_INTR_EN);
-+ complete(&snfi->done);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static int mtk_snfi_enable_clk(struct device *dev, struct mtk_snfi_clk *clk)
-+{
-+ int ret;
-+
-+ ret = clk_prepare_enable(clk->nfi_clk);
-+ if (ret) {
-+ dev_err(dev, "failed to enable nfi clk\n");
-+ return ret;
-+ }
-+
-+ ret = clk_prepare_enable(clk->spi_clk);
-+ if (ret) {
-+ dev_err(dev, "failed to enable spi clk\n");
-+ clk_disable_unprepare(clk->nfi_clk);
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static void mtk_snfi_disable_clk(struct mtk_snfi_clk *clk)
-+{
-+ clk_disable_unprepare(clk->nfi_clk);
-+ clk_disable_unprepare(clk->spi_clk);
-+}
-+
-+static int mtk_snfi_reset(struct mtk_snfi *snfi)
-+{
-+ u32 val;
-+ int ret;
-+
-+ /* SW reset controller */
-+ val = readl(snfi->regs + SNFI_MISC_CTL) | SW_RST;
-+ writel(val, snfi->regs + SNFI_MISC_CTL);
-+
-+ ret = readw_poll_timeout(snfi->regs + SNFI_STA_CTL1, val,
-+ !(val & SPI_STATE_IDLE), 50,
-+ MTK_RESET_TIMEOUT);
-+ if (ret) {
-+ dev_warn(snfi->dev, "spi state active in reset [0x%x] = 0x%x\n",
-+ SNFI_STA_CTL1, val);
-+ return ret;
-+ }
-+
-+ val = readl(snfi->regs + SNFI_MISC_CTL);
-+ val &= ~SW_RST;
-+ writel(val, snfi->regs + SNFI_MISC_CTL);
-+
-+ /* reset all registers and force the NFI master to terminate */
-+ writew(CON_FIFO_FLUSH | CON_NFI_RST, snfi->regs + NFI_CON);
-+ ret = readw_poll_timeout(snfi->regs + NFI_STA, val,
-+ !(val & (NFI_FSM_MASK | NAND_FSM_MASK)), 50,
-+ MTK_RESET_TIMEOUT);
-+ if (ret) {
-+ dev_warn(snfi->dev, "nfi active in reset [0x%x] = 0x%x\n",
-+ NFI_STA, val);
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int mtk_snfi_set_spare_per_sector(struct spinand_device *spinand,
-+ const struct mtk_snfi_caps *caps,
-+ u32 *sps)
-+{
-+ struct mtd_info *mtd = spinand_to_mtd(spinand);
-+ const u8 *spare = caps->spare_size;
-+ u32 sectors, i, closest_spare = 0;
-+
-+ sectors = mtd->writesize / caps->nand_sec_size;
-+ *sps = mtd->oobsize / sectors;
-+
-+ if (*sps < MTK_SNFC_MIN_SPARE)
-+ return -EINVAL;
-+
-+ for (i = 0; i < caps->num_spare_size; i++) {
-+ if (*sps >= spare[i] && spare[i] >= spare[closest_spare]) {
-+ closest_spare = i;
-+ if (*sps == spare[i])
-+ break;
-+ }
-+ }
-+
-+ *sps = spare[closest_spare];
-+
-+ return 0;
-+}
-+
-+static void mtk_snfi_read_fdm_data(struct spi_mem *mem,
-+ u32 sectors)
-+{
-+ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master);
-+ const struct mtk_snfi_caps *caps = snfi->caps;
-+ u32 vall, valm;
-+ int i, j;
-+ u8 *oobptr;
-+
-+ for (i = 0; i < sectors; i++) {
-+ oobptr = oob_ptr(mem, i);
-+ vall = readl(snfi->regs + NFI_FDML(i));
-+ valm = readl(snfi->regs + NFI_FDMM(i));
-+
-+ for (j = 0; j < caps->nand_fdm_size; j++)
-+ oobptr[j] = (j >= 4 ? valm : vall) >> ((j % 4) * 8);
-+ }
-+}
-+
-+static void mtk_snfi_write_fdm_data(struct spi_mem *mem,
-+ u32 sectors)
-+{
-+ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master);
-+ const struct mtk_snfi_caps *caps = snfi->caps;
-+ u32 vall, valm;
-+ int i, j;
-+ u8 *oobptr;
-+
-+ for (i = 0; i < sectors; i++) {
-+ oobptr = oob_ptr(mem, i);
-+ vall = 0;
-+ valm = 0;
-+ for (j = 0; j < 8; j++) {
-+ if (j < 4)
-+ vall |= (j < caps->nand_fdm_size ? oobptr[j] :
-+ 0xff) << (j * 8);
-+ else
-+ valm |= (j < caps->nand_fdm_size ? oobptr[j] :
-+ 0xff) << ((j - 4) * 8);
-+ }
-+ writel(vall, snfi->regs + NFI_FDML(i));
-+ writel(valm, snfi->regs + NFI_FDMM(i));
-+ }
-+}
-+
-+static int mtk_snfi_update_ecc_stats(struct spi_mem *mem,
-+ u8 *buf, u32 sectors)
-+{
-+ struct spinand_device *spinand = spi_mem_get_drvdata(mem);
-+ struct mtd_info *mtd = spinand_to_mtd(spinand);
-+ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master);
-+ struct mtk_ecc_stats stats;
-+ int rc, i;
-+
-+ rc = readl(snfi->regs + NFI_STA) & STA_EMP_PAGE;
-+ if (rc) {
-+ memset(buf, 0xff, sectors * snfi->caps->nand_sec_size);
-+ for (i = 0; i < sectors; i++)
-+ memset(spinand->oobbuf, 0xff,
-+ snfi->caps->nand_fdm_size);
-+ return 0;
-+ }
-+
-+ mtk_ecc_get_stats(snfi->ecc, &stats, sectors);
-+ mtd->ecc_stats.corrected += stats.corrected;
-+ mtd->ecc_stats.failed += stats.failed;
-+
-+ return 0;
-+}
-+
-+static int mtk_snfi_hw_runtime_config(struct spi_mem *mem)
-+{
-+ struct spinand_device *spinand = spi_mem_get_drvdata(mem);
-+ struct mtd_info *mtd = spinand_to_mtd(spinand);
-+ struct nand_device *nand = mtd_to_nanddev(mtd);
-+ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master);
-+ const struct mtk_snfi_caps *caps = snfi->caps;
-+ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand;
-+ u32 fmt, spare, i = 0;
-+ int ret;
-+
-+ ret = mtk_snfi_set_spare_per_sector(spinand, caps, &spare);
-+ if (ret)
-+ return ret;
-+
-+ /* calculate usable oob bytes for ecc parity data */
-+ snfi_nand->spare_per_sector = spare;
-+ spare -= caps->nand_fdm_size;
-+
-+ nand->memorg.oobsize = snfi_nand->spare_per_sector
-+ * (mtd->writesize / caps->nand_sec_size);
-+ mtd->oobsize = nanddev_per_page_oobsize(nand);
-+
-+ snfi->ecc_cfg.strength = (spare << 3) / caps->ecc_parity_bits;
-+ mtk_ecc_adjust_strength(snfi->ecc, &snfi->ecc_cfg.strength);
-+
-+ switch (mtd->writesize) {
-+ case 512:
-+ fmt = PAGEFMT_512;
-+ break;
-+ case KB(2):
-+ fmt = PAGEFMT_2K;
-+ break;
-+ case KB(4):
-+ fmt = PAGEFMT_4K;
-+ break;
-+ default:
-+ dev_err(snfi->dev, "invalid page len: %d\n", mtd->writesize);
-+ return -EINVAL;
-+ }
-+
-+ /* Setup PageFormat */
-+ while (caps->spare_size[i] != snfi_nand->spare_per_sector) {
-+ i++;
-+ if (i == (caps->num_spare_size - 1)) {
-+ dev_err(snfi->dev, "invalid spare size %d\n",
-+ snfi_nand->spare_per_sector);
-+ return -EINVAL;
-+ }
-+ }
-+
-+ fmt |= i << caps->pageformat_spare_shift;
-+ fmt |= caps->nand_fdm_size << PAGEFMT_FDM_SHIFT;
-+ fmt |= caps->nand_fdm_ecc_size << PAGEFMT_FDM_ECC_SHIFT;
-+ writel(fmt, snfi->regs + NFI_PAGEFMT);
-+
-+ snfi->ecc_cfg.len = caps->nand_sec_size + caps->nand_fdm_ecc_size;
-+
-+ mtk_snfi_set_bad_mark_ctl(&snfi_nand->bad_mark, mem);
-+
-+ return 0;
-+}
-+
-+static int mtk_snfi_read_from_cache(struct spi_mem *mem,
-+ const struct spi_mem_op *op, int oob_on)
-+{
-+ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master);
-+ struct spinand_device *spinand = spi_mem_get_drvdata(mem);
-+ struct mtd_info *mtd = spinand_to_mtd(spinand);
-+ u32 sectors = mtd->writesize / snfi->caps->nand_sec_size;
-+ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand;
-+ u32 reg, len, col_addr = 0;
-+ int dummy_cycle, ret;
-+ dma_addr_t dma_addr;
-+
-+ len = sectors * (snfi->caps->nand_sec_size
-+ + snfi_nand->spare_per_sector);
-+
-+ dma_addr = dma_map_single(snfi->dev, snfi->buffer,
-+ len, DMA_FROM_DEVICE);
-+ ret = dma_mapping_error(snfi->dev, dma_addr);
-+ if (ret) {
-+ dev_err(snfi->dev, "dma mapping error\n");
-+ return -EINVAL;
-+ }
-+
-+ /* set Read cache command and dummy cycle */
-+ dummy_cycle = (op->dummy.nbytes << 3) >> (ffs(op->dummy.buswidth) - 1);
-+ reg = ((op->cmd.opcode & RD_CMD_MASK) |
-+ (dummy_cycle << RD_DUMMY_SHIFT));
-+ writel(reg, snfi->regs + SNFI_RD_CTL2);
-+
-+ writel((col_addr & RD_ADDR_MASK), snfi->regs + SNFI_RD_CTL3);
-+
-+ reg = readl(snfi->regs + SNFI_MISC_CTL);
-+ reg |= RD_CUSTOM_EN;
-+ reg &= ~(RD_MODE_MASK | WR_X4_EN);
-+
-+ /* set data and addr buswidth */
-+ if (op->data.buswidth == 4)
-+ reg |= RD_MODE_X4;
-+ else if (op->data.buswidth == 2)
-+ reg |= RD_MODE_X2;
-+
-+ if (op->addr.buswidth == 4 || op->addr.buswidth == 2)
-+ reg |= RD_QDUAL_IO;
-+ writel(reg, snfi->regs + SNFI_MISC_CTL);
-+
-+ writel(len, snfi->regs + SNFI_MISC_CTL2);
-+ writew(sectors << CON_SEC_SHIFT, snfi->regs + NFI_CON);
-+ reg = readw(snfi->regs + NFI_CNFG);
-+ reg |= CNFG_READ_EN | CNFG_DMA_BURST_EN | CNFG_DMA | CNFG_OP_CUST;
-+
-+ if (!oob_on) {
-+ reg |= CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN;
-+ writew(reg, snfi->regs + NFI_CNFG);
-+
-+ snfi->ecc_cfg.mode = ECC_NFI_MODE;
-+ snfi->ecc_cfg.sectors = sectors;
-+ snfi->ecc_cfg.op = ECC_DECODE;
-+ ret = mtk_ecc_enable(snfi->ecc, &snfi->ecc_cfg);
-+ if (ret) {
-+ dev_err(snfi->dev, "ecc enable failed\n");
-+ /* clear NFI_CNFG */
-+ reg &= ~(CNFG_READ_EN | CNFG_DMA_BURST_EN | CNFG_DMA |
-+ CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN);
-+ writew(reg, snfi->regs + NFI_CNFG);
-+ goto out;
-+ }
-+ } else {
-+ writew(reg, snfi->regs + NFI_CNFG);
-+ }
-+
-+ writel(lower_32_bits(dma_addr), snfi->regs + NFI_STRADDR);
-+ readw(snfi->regs + NFI_INTR_STA);
-+ writew(INTR_AHB_DONE_EN, snfi->regs + NFI_INTR_EN);
-+
-+ init_completion(&snfi->done);
-+
-+ /* set dummy command to trigger NFI enter SPI mode */
-+ writew(NAND_CMD_DUMMYREAD, snfi->regs + NFI_CMD);
-+ reg = readl(snfi->regs + NFI_CON) | CON_BRD;
-+ writew(reg, snfi->regs + NFI_CON);
-+
-+ ret = wait_for_completion_timeout(&snfi->done, msecs_to_jiffies(500));
-+ if (!ret) {
-+ dev_err(snfi->dev, "read ahb done timeout\n");
-+ writew(0, snfi->regs + NFI_INTR_EN);
-+ ret = -ETIMEDOUT;
-+ goto out;
-+ }
-+
-+ ret = readl_poll_timeout_atomic(snfi->regs + NFI_BYTELEN, reg,
-+ ADDRCNTR_SEC(reg) >= sectors, 10,
-+ MTK_TIMEOUT);
-+ if (ret < 0) {
-+ dev_err(snfi->dev, "polling read byte len timeout\n");
-+ ret = -EIO;
-+ } else {
-+ if (!oob_on) {
-+ ret = mtk_ecc_wait_done(snfi->ecc, ECC_DECODE);
-+ if (ret) {
-+ dev_warn(snfi->dev, "wait ecc done timeout\n");
-+ } else {
-+ mtk_snfi_update_ecc_stats(mem, snfi->buffer,
-+ sectors);
-+ mtk_snfi_read_fdm_data(mem, sectors);
-+ }
-+ }
-+ }
-+
-+ if (oob_on)
-+ goto out;
-+
-+ mtk_ecc_disable(snfi->ecc);
-+out:
-+ dma_unmap_single(snfi->dev, dma_addr, len, DMA_FROM_DEVICE);
-+ writel(0, snfi->regs + NFI_CON);
-+ writel(0, snfi->regs + NFI_CNFG);
-+ reg = readl(snfi->regs + SNFI_MISC_CTL);
-+ reg &= ~RD_CUSTOM_EN;
-+ writel(reg, snfi->regs + SNFI_MISC_CTL);
-+
-+ return ret;
-+}
-+
-+static int mtk_snfi_write_to_cache(struct spi_mem *mem,
-+ const struct spi_mem_op *op,
-+ int oob_on)
-+{
-+ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master);
-+ struct spinand_device *spinand = spi_mem_get_drvdata(mem);
-+ struct mtd_info *mtd = spinand_to_mtd(spinand);
-+ u32 sectors = mtd->writesize / snfi->caps->nand_sec_size;
-+ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand;
-+ u32 reg, len, col_addr = 0;
-+ dma_addr_t dma_addr;
-+ int ret;
-+
-+ len = sectors * (snfi->caps->nand_sec_size
-+ + snfi_nand->spare_per_sector);
-+
-+ dma_addr = dma_map_single(snfi->dev, snfi->buffer, len,
-+ DMA_TO_DEVICE);
-+ ret = dma_mapping_error(snfi->dev, dma_addr);
-+ if (ret) {
-+ dev_err(snfi->dev, "dma mapping error\n");
-+ return -EINVAL;
-+ }
-+
-+ /* set program load cmd and address */
-+ reg = (op->cmd.opcode << WR_LOAD_CMD_SHIFT);
-+ writel(reg, snfi->regs + SNFI_PG_CTL1);
-+ writel(col_addr & WR_LOAD_ADDR_MASK, snfi->regs + SNFI_PG_CTL2);
-+
-+ reg = readl(snfi->regs + SNFI_MISC_CTL);
-+ reg |= WR_CUSTOM_EN;
-+ reg &= ~(RD_MODE_MASK | WR_X4_EN);
-+
-+ if (op->data.buswidth == 4)
-+ reg |= WR_X4_EN;
-+ writel(reg, snfi->regs + SNFI_MISC_CTL);
-+
-+ writel(len << WR_LEN_SHIFT, snfi->regs + SNFI_MISC_CTL2);
-+ writew(sectors << CON_SEC_SHIFT, snfi->regs + NFI_CON);
-+
-+ reg = readw(snfi->regs + NFI_CNFG);
-+ reg &= ~(CNFG_READ_EN | CNFG_BYTE_RW);
-+ reg |= CNFG_DMA | CNFG_DMA_BURST_EN | CNFG_OP_PROGRAM;
-+
-+ if (!oob_on) {
-+ reg |= CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN;
-+ writew(reg, snfi->regs + NFI_CNFG);
-+
-+ snfi->ecc_cfg.mode = ECC_NFI_MODE;
-+ snfi->ecc_cfg.op = ECC_ENCODE;
-+ ret = mtk_ecc_enable(snfi->ecc, &snfi->ecc_cfg);
-+ if (ret) {
-+ dev_err(snfi->dev, "ecc enable failed\n");
-+ /* clear NFI_CNFG */
-+ reg &= ~(CNFG_DMA_BURST_EN | CNFG_DMA |
-+ CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN);
-+ writew(reg, snfi->regs + NFI_CNFG);
-+ dma_unmap_single(snfi->dev, dma_addr, len,
-+ DMA_FROM_DEVICE);
-+ goto out;
-+ }
-+ /* write OOB into the FDM registers (OOB area in MTK NAND) */
-+ mtk_snfi_write_fdm_data(mem, sectors);
-+ } else {
-+ writew(reg, snfi->regs + NFI_CNFG);
-+ }
-+ writel(lower_32_bits(dma_addr), snfi->regs + NFI_STRADDR);
-+ readw(snfi->regs + NFI_INTR_STA);
-+ writew(INTR_AHB_DONE_EN, snfi->regs + NFI_INTR_EN);
-+
-+ init_completion(&snfi->done);
-+
-+ /* set dummy command to trigger NFI enter SPI mode */
-+ writew(NAND_CMD_DUMMYPROG, snfi->regs + NFI_CMD);
-+ reg = readl(snfi->regs + NFI_CON) | CON_BWR;
-+ writew(reg, snfi->regs + NFI_CON);
-+
-+ ret = wait_for_completion_timeout(&snfi->done, msecs_to_jiffies(500));
-+ if (!ret) {
-+ dev_err(snfi->dev, "custom program done timeout\n");
-+ writew(0, snfi->regs + NFI_INTR_EN);
-+ ret = -ETIMEDOUT;
-+ goto ecc_disable;
-+ }
-+
-+ ret = readl_poll_timeout_atomic(snfi->regs + NFI_ADDRCNTR, reg,
-+ ADDRCNTR_SEC(reg) >= sectors,
-+ 10, MTK_TIMEOUT);
-+ if (ret)
-+ dev_err(snfi->dev, "hwecc write timeout\n");
-+
-+ecc_disable:
-+ mtk_ecc_disable(snfi->ecc);
-+
-+out:
-+ dma_unmap_single(snfi->dev, dma_addr, len, DMA_TO_DEVICE);
-+ writel(0, snfi->regs + NFI_CON);
-+ writel(0, snfi->regs + NFI_CNFG);
-+ reg = readl(snfi->regs + SNFI_MISC_CTL);
-+ reg &= ~WR_CUSTOM_EN;
-+ writel(reg, snfi->regs + SNFI_MISC_CTL);
-+
-+ return ret;
-+}
-+
-+static int mtk_snfi_read(struct spi_mem *mem,
-+ const struct spi_mem_op *op)
-+{
-+ struct spinand_device *spinand = spi_mem_get_drvdata(mem);
-+ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master);
-+ struct mtd_info *mtd = spinand_to_mtd(spinand);
-+ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand;
-+ u32 col_addr = op->addr.val;
-+ int i, ret, sectors, oob_on = false;
-+
-+ if (col_addr == mtd->writesize)
-+ oob_on = true;
-+
-+ ret = mtk_snfi_read_from_cache(mem, op, oob_on);
-+ if (ret) {
-+ dev_warn(snfi->dev, "read from cache fail\n");
-+ return ret;
-+ }
-+
-+ sectors = mtd->writesize / snfi->caps->nand_sec_size;
-+ for (i = 0; i < sectors; i++) {
-+ if (oob_on)
-+ memcpy(oob_ptr(mem, i),
-+ mtk_oob_ptr(mem, snfi->buffer, i),
-+ snfi->caps->nand_fdm_size);
-+
-+ if (i == snfi_nand->bad_mark.sec && snfi->caps->bad_mark_swap)
-+ snfi_nand->bad_mark.bm_swap(mem, snfi->buffer,
-+ oob_on);
-+ }
-+
-+ if (!oob_on)
-+ memcpy(spinand->databuf, snfi->buffer, mtd->writesize);
-+
-+ return ret;
-+}
-+
-+static int mtk_snfi_write(struct spi_mem *mem,
-+ const struct spi_mem_op *op)
-+{
-+ struct spinand_device *spinand = spi_mem_get_drvdata(mem);
-+ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master);
-+ struct mtd_info *mtd = spinand_to_mtd(spinand);
-+ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand;
-+ u32 ret, i, sectors, col_addr = op->addr.val;
-+ int oob_on = false;
-+
-+ if (col_addr == mtd->writesize)
-+ oob_on = true;
-+
-+ sectors = mtd->writesize / snfi->caps->nand_sec_size;
-+ memset(snfi->buffer, 0xff, mtd->writesize + mtd->oobsize);
-+
-+ if (!oob_on)
-+ memcpy(snfi->buffer, spinand->databuf, mtd->writesize);
-+
-+ for (i = 0; i < sectors; i++) {
-+ if (i == snfi_nand->bad_mark.sec && snfi->caps->bad_mark_swap)
-+ snfi_nand->bad_mark.bm_swap(mem, snfi->buffer, oob_on);
-+
-+ if (oob_on)
-+ memcpy(mtk_oob_ptr(mem, snfi->buffer, i),
-+ oob_ptr(mem, i),
-+ snfi->caps->nand_fdm_size);
-+ }
-+
-+ ret = mtk_snfi_write_to_cache(mem, op, oob_on);
-+ if (ret)
-+ dev_warn(snfi->dev, "write to cache fail\n");
-+
-+ return ret;
-+}
-+
-+static int mtk_snfi_command_exec(struct mtk_snfi *snfi,
-+ const u8 *txbuf, u8 *rxbuf,
-+ const u32 txlen, const u32 rxlen)
-+{
-+ u32 tmp, i, j, reg, m;
-+ u8 *p_tmp = (u8 *)(&tmp);
-+ int ret = 0;
-+
-+ /* Moving tx data to NFI_SPI GPRAM */
-+ for (i = 0, m = 0; i < txlen; ) {
-+ for (j = 0, tmp = 0; i < txlen && j < 4; i++, j++)
-+ p_tmp[j] = txbuf[i];
-+
-+ writel(tmp, snfi->regs + SNFI_GPRAM_DATA + m);
-+ m += 4;
-+ }
-+
-+ writel(txlen, snfi->regs + SNFI_MAC_OUTL);
-+ writel(rxlen, snfi->regs + SNFI_MAC_INL);
-+ ret = mtk_snfi_mac_op(snfi);
-+ if (ret)
-+ return ret;
-+
-+ /* For NULL input data, this loop will be skipped */
-+ if (rxlen)
-+ for (i = 0, m = 0; i < rxlen; ) {
-+ reg = readl(snfi->regs +
-+ SNFI_GPRAM_DATA + m);
-+ for (j = 0; i < rxlen && j < 4; i++, j++, rxbuf++) {
-+ if (m == 0 && i == 0)
-+ j = i + txlen;
-+ *rxbuf = (reg >> (j * 8)) & 0xFF;
-+ }
-+ m += 4;
-+ }
-+
-+ return ret;
-+}
-+
-+/*
-+ * mtk_snfi_exec_op - to process command/data to send to the
-+ * SPI NAND by mtk controller
-+ */
-+static int mtk_snfi_exec_op(struct spi_mem *mem,
-+ const struct spi_mem_op *op)
-+
-+{
-+ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master);
-+ struct spinand_device *spinand = spi_mem_get_drvdata(mem);
-+ struct mtd_info *mtd = spinand_to_mtd(spinand);
-+ struct nand_device *nand = mtd_to_nanddev(mtd);
-+ const struct spi_mem_op *read_cache;
-+ const struct spi_mem_op *write_cache;
-+ const struct spi_mem_op *update_cache;
-+ u32 tmpbufsize, txlen = 0, rxlen = 0;
-+ u8 *txbuf, *rxbuf = NULL, *buf;
-+ int i, ret = 0;
-+
-+ ret = mtk_snfi_reset(snfi);
-+ if (ret) {
-+ dev_warn(snfi->dev, "reset spi memory controller fail\n");
-+ return ret;
-+ }
-+
-+ /*if bbt initial, framework have detect nand information */
-+ if (nand->bbt.cache) {
-+ read_cache = spinand->op_templates.read_cache;
-+ write_cache = spinand->op_templates.write_cache;
-+ update_cache = spinand->op_templates.update_cache;
-+
-+ ret = mtk_snfi_hw_runtime_config(mem);
-+ if (ret)
-+ return ret;
-+
-+ /* For Read/Write with cache, Erase use framework flow */
-+ if (op->cmd.opcode == read_cache->cmd.opcode) {
-+ ret = mtk_snfi_read(mem, op);
-+ if (ret)
-+ dev_warn(snfi->dev, "snfi read fail\n");
-+
-+ return ret;
-+ } else if ((op->cmd.opcode == write_cache->cmd.opcode)
-+ || (op->cmd.opcode == update_cache->cmd.opcode)) {
-+ ret = mtk_snfi_write(mem, op);
-+ if (ret)
-+ dev_warn(snfi->dev, "snfi write fail\n");
-+
-+ return ret;
-+ }
-+ }
-+
-+ tmpbufsize = sizeof(op->cmd.opcode) + op->addr.nbytes +
-+ op->dummy.nbytes + op->data.nbytes;
-+
-+ txbuf = kzalloc(tmpbufsize, GFP_KERNEL);
-+ if (!txbuf)
-+ return -ENOMEM;
-+
-+ txbuf[txlen++] = op->cmd.opcode;
-+
-+ if (op->addr.nbytes)
-+ for (i = 0; i < op->addr.nbytes; i++)
-+ txbuf[txlen++] = op->addr.val >>
-+ (8 * (op->addr.nbytes - i - 1));
-+
-+ txlen += op->dummy.nbytes;
-+
-+ if (op->data.dir == SPI_MEM_DATA_OUT)
-+ for (i = 0; i < op->data.nbytes; i++) {
-+ buf = (u8 *)op->data.buf.out;
-+ txbuf[txlen++] = buf[i];
-+ }
-+
-+ if (op->data.dir == SPI_MEM_DATA_IN) {
-+ rxbuf = (u8 *)op->data.buf.in;
-+ rxlen += op->data.nbytes;
-+ }
-+
-+ ret = mtk_snfi_command_exec(snfi, txbuf, rxbuf, txlen, rxlen);
-+ kfree(txbuf);
-+
-+ return ret;
-+}
-+
-+static int mtk_snfi_init(struct mtk_snfi *snfi)
-+{
-+ int ret;
-+
-+ /* Reset the state machine and data FIFO */
-+ ret = mtk_snfi_reset(snfi);
-+ if (ret) {
-+ dev_warn(snfi->dev, "MTK reset controller fail\n");
-+ return ret;
-+ }
-+
-+ snfi->buffer = devm_kzalloc(snfi->dev, 4096 + 256, GFP_KERNEL);
-+ if (!snfi->buffer)
-+ return -ENOMEM;
-+
-+ /* Clear interrupt, read clear. */
-+ readw(snfi->regs + NFI_INTR_STA);
-+ writew(0, snfi->regs + NFI_INTR_EN);
-+
-+ writel(0, snfi->regs + NFI_CON);
-+ writel(0, snfi->regs + NFI_CNFG);
-+
-+ /* Change to NFI_SPI mode. */
-+ writel(SNFI_MODE_EN, snfi->regs + SNFI_CNFG);
-+
-+ return 0;
-+}
-+
-+static int mtk_snfi_check_buswidth(u8 width)
-+{
-+ switch (width) {
-+ case 1:
-+ case 2:
-+ case 4:
-+ return 0;
-+
-+ default:
-+ break;
-+ }
-+
-+ return -ENOTSUPP;
-+}
-+
-+static bool mtk_snfi_supports_op(struct spi_mem *mem,
-+ const struct spi_mem_op *op)
-+{
-+ int ret = 0;
-+
-+ /* For MTK Spi Nand controller, cmd buswidth just support 1 bit*/
-+ if (op->cmd.buswidth != 1)
-+ ret = -ENOTSUPP;
-+
-+ if (op->addr.nbytes)
-+ ret |= mtk_snfi_check_buswidth(op->addr.buswidth);
-+
-+ if (op->dummy.nbytes)
-+ ret |= mtk_snfi_check_buswidth(op->dummy.buswidth);
-+
-+ if (op->data.nbytes)
-+ ret |= mtk_snfi_check_buswidth(op->data.buswidth);
-+
-+ if (ret)
-+ return false;
-+
-+ return true;
-+}
-+
-+static const struct spi_controller_mem_ops mtk_snfi_ops = {
-+ .supports_op = mtk_snfi_supports_op,
-+ .exec_op = mtk_snfi_exec_op,
-+};
-+
-+static const struct mtk_snfi_caps snfi_mt7622 = {
-+ .spare_size = spare_size_mt7622,
-+ .num_spare_size = 4,
-+ .nand_sec_size = 512,
-+ .nand_fdm_size = 8,
-+ .nand_fdm_ecc_size = 1,
-+ .ecc_parity_bits = 13,
-+ .pageformat_spare_shift = 4,
-+ .bad_mark_swap = 0,
-+};
-+
-+static const struct mtk_snfi_caps snfi_mt7629 = {
-+ .spare_size = spare_size_mt7622,
-+ .num_spare_size = 4,
-+ .nand_sec_size = 512,
-+ .nand_fdm_size = 8,
-+ .nand_fdm_ecc_size = 1,
-+ .ecc_parity_bits = 13,
-+ .pageformat_spare_shift = 4,
-+ .bad_mark_swap = 1,
-+};
-+
-+static const struct of_device_id mtk_snfi_id_table[] = {
-+ { .compatible = "mediatek,mt7622-snfi", .data = &snfi_mt7622, },
-+ { .compatible = "mediatek,mt7629-snfi", .data = &snfi_mt7629, },
-+ { /* sentinel */ }
-+};
-+
-+static int mtk_snfi_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct device_node *np = dev->of_node;
-+ struct spi_controller *ctlr;
-+ struct mtk_snfi *snfi;
-+ struct resource *res;
-+ int ret = 0, irq;
-+
-+ ctlr = spi_alloc_master(&pdev->dev, sizeof(*snfi));
-+ if (!ctlr)
-+ return -ENOMEM;
-+
-+ snfi = spi_controller_get_devdata(ctlr);
-+ snfi->caps = of_device_get_match_data(dev);
-+ snfi->dev = dev;
-+
-+ snfi->ecc = of_mtk_ecc_get(np);
-+ if (IS_ERR_OR_NULL(snfi->ecc))
-+ goto err_put_master;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ snfi->regs = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(snfi->regs)) {
-+ ret = PTR_ERR(snfi->regs);
-+ goto release_ecc;
-+ }
-+
-+ /* find the clocks */
-+ snfi->clk.nfi_clk = devm_clk_get(dev, "nfi_clk");
-+ if (IS_ERR(snfi->clk.nfi_clk)) {
-+ dev_err(dev, "no nfi clk\n");
-+ ret = PTR_ERR(snfi->clk.nfi_clk);
-+ goto release_ecc;
-+ }
-+
-+ snfi->clk.spi_clk = devm_clk_get(dev, "spi_clk");
-+ if (IS_ERR(snfi->clk.spi_clk)) {
-+ dev_err(dev, "no spi clk\n");
-+ ret = PTR_ERR(snfi->clk.spi_clk);
-+ goto release_ecc;
-+ }
-+
-+ ret = mtk_snfi_enable_clk(dev, &snfi->clk);
-+ if (ret)
-+ goto release_ecc;
-+
-+ /* find the irq */
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq < 0) {
-+ dev_err(dev, "no snfi irq resource\n");
-+ ret = -EINVAL;
-+ goto clk_disable;
-+ }
-+
-+ ret = devm_request_irq(dev, irq, mtk_snfi_irq, 0, "mtk-snfi", snfi);
-+ if (ret) {
-+ dev_err(dev, "failed to request snfi irq\n");
-+ goto clk_disable;
-+ }
-+
-+ ret = dma_set_mask(dev, DMA_BIT_MASK(32));
-+ if (ret) {
-+ dev_err(dev, "failed to set dma mask\n");
-+ goto clk_disable;
-+ }
-+
-+ ctlr->dev.of_node = np;
-+ ctlr->mem_ops = &mtk_snfi_ops;
-+
-+ platform_set_drvdata(pdev, snfi);
-+ ret = mtk_snfi_init(snfi);
-+ if (ret) {
-+ dev_err(dev, "failed to init snfi\n");
-+ goto clk_disable;
-+ }
-+
-+ ret = devm_spi_register_master(dev, ctlr);
-+ if (ret)
-+ goto clk_disable;
-+
-+ return 0;
-+
-+clk_disable:
-+ mtk_snfi_disable_clk(&snfi->clk);
-+
-+release_ecc:
-+ mtk_ecc_release(snfi->ecc);
-+
-+err_put_master:
-+ spi_master_put(ctlr);
-+
-+ dev_err(dev, "MediaTek SPI NAND interface probe failed %d\n", ret);
-+ return ret;
-+}
-+
-+static int mtk_snfi_remove(struct platform_device *pdev)
-+{
-+ struct mtk_snfi *snfi = platform_get_drvdata(pdev);
-+
-+ mtk_snfi_disable_clk(&snfi->clk);
-+
-+ return 0;
-+}
-+
-+static int mtk_snfi_suspend(struct platform_device *pdev, pm_message_t state)
-+{
-+ struct mtk_snfi *snfi = platform_get_drvdata(pdev);
-+
-+ mtk_snfi_disable_clk(&snfi->clk);
-+
-+ return 0;
-+}
-+
-+static int mtk_snfi_resume(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct mtk_snfi *snfi = dev_get_drvdata(dev);
-+ int ret;
-+
-+ ret = mtk_snfi_enable_clk(dev, &snfi->clk);
-+ if (ret)
-+ return ret;
-+
-+ ret = mtk_snfi_init(snfi);
-+ if (ret)
-+ dev_err(dev, "failed to init snfi controller\n");
-+
-+ return ret;
-+}
-+
-+static struct platform_driver mtk_snfi_driver = {
-+ .driver = {
-+ .name = "mtk-snfi",
-+ .of_match_table = mtk_snfi_id_table,
-+ },
-+ .probe = mtk_snfi_probe,
-+ .remove = mtk_snfi_remove,
-+ .suspend = mtk_snfi_suspend,
-+ .resume = mtk_snfi_resume,
-+};
-+
-+module_platform_driver(mtk_snfi_driver);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_AUTHOR("Xiangsheng Hou <xiangsheng.hou@mediatek.com>");
-+MODULE_DESCRIPTION("Mediatek SPI Memory Interface Driver");
diff --git a/target/linux/mediatek/patches-5.4/0307-dts-mt7629-add-snand-support.patch b/target/linux/mediatek/patches-5.4/0307-dts-mt7629-add-snand-support.patch
deleted file mode 100644
index 233face4c5..0000000000
--- a/target/linux/mediatek/patches-5.4/0307-dts-mt7629-add-snand-support.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From c813fbe806257c574240770ef716fbee19f7dbfa Mon Sep 17 00:00:00 2001
-From: Xiangsheng Hou <xiangsheng.hou@mediatek.com>
-Date: Thu, 6 Jun 2019 16:29:04 +0800
-Subject: [PATCH] spi: spi-mem: Mediatek: Add SPI Nand support for MT7629
-
-Signed-off-by: Xiangsheng Hou <xiangsheng.hou@mediatek.com>
----
- arch/arm/boot/dts/mt7629-rfb.dts | 45 ++++++++++++++++++++++++++++++++
- arch/arm/boot/dts/mt7629.dtsi | 22 ++++++++++++++++
- 3 files changed, 79 insertions(+)
-
---- a/arch/arm/boot/dts/mt7629.dtsi
-+++ b/arch/arm/boot/dts/mt7629.dtsi
-@@ -258,6 +258,28 @@
- status = "disabled";
- };
-
-+ bch: ecc@1100e000 {
-+ compatible = "mediatek,mt7622-ecc";
-+ reg = <0x1100e000 0x1000>;
-+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_LOW>;
-+ clocks = <&pericfg CLK_PERI_NFIECC_PD>;
-+ clock-names = "nfiecc_clk";
-+ status = "disabled";
-+ };
-+
-+ snfi: spi@1100d000 {
-+ compatible = "mediatek,mt7629-snfi";
-+ reg = <0x1100d000 0x1000>;
-+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
-+ clocks = <&pericfg CLK_PERI_NFI_PD>,
-+ <&pericfg CLK_PERI_SNFI_PD>;
-+ clock-names = "nfi_clk", "spi_clk";
-+ ecc-engine = <&bch>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
- spi: spi@1100a000 {
- compatible = "mediatek,mt7629-spi",
- "mediatek,mt7622-spi";
---- a/arch/arm/boot/dts/mt7629-rfb.dts
-+++ b/arch/arm/boot/dts/mt7629-rfb.dts
-@@ -281,6 +281,52 @@
- };
- };
-
-+&bch {
-+ status = "okay";
-+};
-+
-+&snfi {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&serial_nand_pins>;
-+ status = "okay";
-+
-+ spi_nand@0 {
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ compatible = "spi-nand";
-+ spi-max-frequency = <104000000>;
-+ reg = <0>;
-+
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ partition@0 {
-+ label = "Bootloader";
-+ reg = <0x00000 0x0100000>;
-+ read-only;
-+ };
-+
-+ partition@100000 {
-+ label = "Config";
-+ reg = <0x100000 0x0040000>;
-+ };
-+
-+ partition@140000 {
-+ label = "factory";
-+ reg = <0x140000 0x0080000>;
-+ };
-+
-+ partition@1c0000 {
-+ label = "firmware";
-+ reg = <0x1c0000 0x1000000>;
-+ };
-+
-+ };
-+ };
-+};
-+
- &spi {
- pinctrl-names = "default";
- pinctrl-0 = <&spi_pins>;
diff --git a/target/linux/mediatek/patches-5.4/0308-dts-mt7622-add-snand-support.patch b/target/linux/mediatek/patches-5.4/0308-dts-mt7622-add-snand-support.patch
deleted file mode 100644
index b287780d6c..0000000000
--- a/target/linux/mediatek/patches-5.4/0308-dts-mt7622-add-snand-support.patch
+++ /dev/null
@@ -1,96 +0,0 @@
---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -554,6 +554,19 @@
- status = "disabled";
- };
-
-+ snfi: spi@1100d000 {
-+ compatible = "mediatek,mt7622-snfi";
-+ reg = <0 0x1100d000 0 0x1000>;
-+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
-+ clocks = <&pericfg CLK_PERI_NFI_PD>,
-+ <&pericfg CLK_PERI_SNFI_PD>;
-+ clock-names = "nfi_clk", "spi_clk";
-+ ecc-engine = <&bch>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
- nor_flash: spi@11014000 {
- compatible = "mediatek,mt7622-nor",
- "mediatek,mt8173-nor";
---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-@@ -99,7 +99,7 @@
- };
-
- &bch {
-- status = "disabled";
-+ status = "okay";
- };
-
- &btif {
-@@ -551,6 +551,62 @@
- status = "disable";
- };
-
-+&snfi {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&serial_nand_pins>;
-+ status = "okay";
-+
-+ spi_nand@0 {
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ compatible = "spi-nand";
-+ spi-max-frequency = <104000000>;
-+ reg = <0>;
-+
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ partition@0 {
-+ label = "Preloader";
-+ reg = <0x00000 0x0080000>;
-+ read-only;
-+ };
-+
-+ partition@80000 {
-+ label = "ATF";
-+ reg = <0x80000 0x0040000>;
-+ };
-+
-+ partition@c0000 {
-+ label = "Bootloader";
-+ reg = <0xc0000 0x0080000>;
-+ };
-+
-+ partition@140000 {
-+ label = "Config";
-+ reg = <0x140000 0x0080000>;
-+ };
-+
-+ partition@1c0000 {
-+ label = "Factory";
-+ reg = <0x1c0000 0x0040000>;
-+ };
-+
-+ partition@200000 {
-+ label = "firmware";
-+ reg = <0x200000 0x2000000>;
-+ };
-+
-+ partition@2200000 {
-+ label = "User_data";
-+ reg = <0x2200000 0x4000000>;
-+ };
-+ };
-+ };
-+};
-+
- &spi0 {
- pinctrl-names = "default";
- pinctrl-0 = <&spic0_pins>;
diff --git a/target/linux/mediatek/patches-5.4/0310-dts-add-wmac-support-for-mt7622-rfb1.patch b/target/linux/mediatek/patches-5.4/0310-dts-add-wmac-support-for-mt7622-rfb1.patch
deleted file mode 100644
index 84aed89752..0000000000
--- a/target/linux/mediatek/patches-5.4/0310-dts-add-wmac-support-for-mt7622-rfb1.patch
+++ /dev/null
@@ -1,40 +0,0 @@
---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -716,6 +716,17 @@
- status = "disabled";
- };
-
-+ wmac: wmac@18000000 {
-+ compatible = "mediatek,mt7622-wmac";
-+ reg = <0 0x18000000 0 0x100000>;
-+ interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_LOW>;
-+
-+ mediatek,infracfg = <&infracfg>;
-+ status = "disabled";
-+
-+ power-domains = <&scpsys MT7622_POWER_DOMAIN_WB>;
-+ };
-+
- ssusbsys: ssusbsys@1a000000 {
- compatible = "mediatek,mt7622-ssusbsys",
- "syscon";
---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-@@ -589,7 +589,7 @@
- reg = <0x140000 0x0080000>;
- };
-
-- partition@1c0000 {
-+ factory: partition@1c0000 {
- label = "Factory";
- reg = <0x1c0000 0x0040000>;
- };
-@@ -646,3 +646,8 @@
- pinctrl-0 = <&watchdog_pins>;
- status = "okay";
- };
-+
-+&wmac {
-+ mediatek,mtd-eeprom = <&factory 0x0000>;
-+ status = "okay";
-+};
diff --git a/target/linux/mediatek/patches-5.4/0310-mtk-bmt-support.patch b/target/linux/mediatek/patches-5.4/0310-mtk-bmt-support.patch
deleted file mode 100644
index 4cef9f9d5e..0000000000
--- a/target/linux/mediatek/patches-5.4/0310-mtk-bmt-support.patch
+++ /dev/null
@@ -1,837 +0,0 @@
---- a/drivers/mtd/nand/Kconfig
-+++ b/drivers/mtd/nand/Kconfig
-@@ -5,3 +5,7 @@ config MTD_NAND_CORE
- source "drivers/mtd/nand/onenand/Kconfig"
- source "drivers/mtd/nand/raw/Kconfig"
- source "drivers/mtd/nand/spi/Kconfig"
-+
-+config MTD_NAND_MTK_BMT
-+ bool "Support MediaTek NAND Bad-block Management Table"
-+ default n
---- a/drivers/mtd/nand/Makefile
-+++ b/drivers/mtd/nand/Makefile
-@@ -2,6 +2,7 @@
-
- nandcore-objs := core.o bbt.o
- obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o
-+obj-$(CONFIG_MTD_NAND_MTK_BMT) += mtk_bmt.o
-
- obj-y += onenand/
- obj-y += raw/
---- /dev/null
-+++ b/drivers/mtd/nand/mtk_bmt.c
-@@ -0,0 +1,766 @@
-+/*
-+ * Copyright (c) 2017 MediaTek Inc.
-+ * Author: Xiangsheng Hou <xiangsheng.hou@mediatek.com>
-+ * Copyright (c) 2020 Felix Fietkau <nbd@nbd.name>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/slab.h>
-+#include <linux/gfp.h>
-+#include <linux/kernel.h>
-+#include <linux/of.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/mtd/mtk_bmt.h>
-+#include <linux/module.h>
-+#include <linux/debugfs.h>
-+
-+#define MAIN_SIGNATURE_OFFSET 0
-+#define OOB_SIGNATURE_OFFSET 1
-+#define BBPOOL_RATIO 2
-+
-+#define BBT_LOG(fmt, ...) pr_debug("[BBT][%s|%d] "fmt"\n", __func__, __LINE__, ##__VA_ARGS__)
-+
-+/* Maximum 8k blocks */
-+#define BB_TABLE_MAX 0x2000U
-+#define BMT_TABLE_MAX (BB_TABLE_MAX * BBPOOL_RATIO / 100)
-+#define BMT_TBL_DEF_VAL 0x0
-+
-+/*
-+ * Burner Bad Block Table
-+ * --------- Only support SLC Nand Chips!!!!!!!!!!! ----------
-+ */
-+
-+struct bbbt {
-+ char signature[3];
-+ /* This version is used to distinguish the legacy and new algorithm */
-+#define BBMT_VERSION 2
-+ unsigned char version;
-+ /* Below 2 tables will be written in SLC */
-+ u16 bb_tbl[BB_TABLE_MAX];
-+ struct bbmt {
-+ u16 block;
-+#define NO_MAPPED 0
-+#define NORMAL_MAPPED 1
-+#define BMT_MAPPED 2
-+ u16 mapped;
-+ } bmt_tbl[BMT_TABLE_MAX];
-+};
-+
-+static struct bmt_desc {
-+ struct mtd_info *mtd;
-+
-+ int (*_read_oob) (struct mtd_info *mtd, loff_t from,
-+ struct mtd_oob_ops *ops);
-+ int (*_write_oob) (struct mtd_info *mtd, loff_t to,
-+ struct mtd_oob_ops *ops);
-+ const struct nand_ops *nand_ops;
-+
-+ struct bbbt *bbt;
-+
-+ struct dentry *debugfs_dir;
-+
-+ u32 pg_size;
-+ u32 blk_size;
-+ u16 pg_shift;
-+ u16 blk_shift;
-+ /* bbt logical address */
-+ u16 pool_lba;
-+ /* bbt physical address */
-+ u16 pool_pba;
-+ /* Maximum count of bad blocks that the vendor guaranteed */
-+ u16 bb_max;
-+ /* Total blocks of the Nand Chip */
-+ u16 total_blks;
-+ /* The block(n) BMT is located at (bmt_tbl[n]) */
-+ u16 bmt_blk_idx;
-+ /* How many pages needs to store 'struct bbbt' */
-+ u32 bmt_pgs;
-+
-+ /* to compensate for driver level remapping */
-+ u8 oob_offset;
-+} bmtd = {0};
-+
-+static unsigned char *nand_bbt_buf;
-+static unsigned char *nand_data_buf;
-+
-+/* -------- Unit conversions -------- */
-+static inline u32 blk_pg(u16 block)
-+{
-+ return (u32)(block << (bmtd.blk_shift - bmtd.pg_shift));
-+}
-+
-+/* -------- Nand operations wrapper -------- */
-+static inline int
-+bbt_nand_read(u32 page, unsigned char *dat, int dat_len,
-+ unsigned char *fdm, int fdm_len)
-+{
-+ struct mtd_oob_ops ops = {
-+ .mode = MTD_OPS_PLACE_OOB,
-+ .ooboffs = bmtd.oob_offset,
-+ .oobbuf = fdm,
-+ .ooblen = fdm_len,
-+ .datbuf = dat,
-+ .len = dat_len,
-+ };
-+
-+ return bmtd._read_oob(bmtd.mtd, page << bmtd.pg_shift, &ops);
-+}
-+
-+static inline int bbt_nand_erase(u16 block)
-+{
-+ struct nand_device *nand = mtd_to_nanddev(bmtd.mtd);
-+ loff_t addr = (loff_t)block << bmtd.blk_shift;
-+ struct nand_pos pos;
-+
-+ nanddev_offs_to_pos(nand, addr, &pos);
-+ return bmtd.nand_ops->erase(nand, &pos);
-+}
-+
-+/* -------- Bad Blocks Management -------- */
-+static int
-+read_bmt(u16 block, unsigned char *dat, unsigned char *fdm, int fdm_len)
-+{
-+ u32 len = bmtd.bmt_pgs << bmtd.pg_shift;
-+
-+ return bbt_nand_read(blk_pg(block), dat, len, fdm, fdm_len);
-+}
-+
-+static int write_bmt(u16 block, unsigned char *dat)
-+{
-+ struct mtd_oob_ops ops = {
-+ .mode = MTD_OPS_PLACE_OOB,
-+ .ooboffs = OOB_SIGNATURE_OFFSET + bmtd.oob_offset,
-+ .oobbuf = "bmt",
-+ .ooblen = 3,
-+ .datbuf = dat,
-+ .len = bmtd.bmt_pgs << bmtd.pg_shift,
-+ };
-+ loff_t addr = (loff_t)block << bmtd.blk_shift;
-+
-+ return bmtd._write_oob(bmtd.mtd, addr, &ops);
-+}
-+
-+static u16 find_valid_block(u16 block)
-+{
-+ u8 fdm[4];
-+ int ret;
-+ int loop = 0;
-+
-+retry:
-+ if (block >= bmtd.total_blks)
-+ return 0;
-+
-+ ret = bbt_nand_read(blk_pg(block), nand_data_buf, bmtd.pg_size,
-+ fdm, sizeof(fdm));
-+ /* Read the 1st byte of FDM to judge whether it's a bad
-+ * or not
-+ */
-+ if (ret || fdm[0] != 0xff) {
-+ pr_info("nand: found bad block 0x%x\n", block);
-+ if (loop >= bmtd.bb_max) {
-+ pr_info("nand: FATAL ERR: too many bad blocks!!\n");
-+ return 0;
-+ }
-+
-+ loop++;
-+ block++;
-+ goto retry;
-+ }
-+
-+ return block;
-+}
-+
-+/* Find out all bad blocks, and fill in the mapping table */
-+static int scan_bad_blocks(struct bbbt *bbt)
-+{
-+ int i;
-+ u16 block = 0;
-+
-+ /* First time download, the block0 MUST NOT be a bad block,
-+ * this is guaranteed by vendor
-+ */
-+ bbt->bb_tbl[0] = 0;
-+
-+ /*
-+ * Construct the mapping table of Normal data area(non-PMT/BMTPOOL)
-+ * G - Good block; B - Bad block
-+ * ---------------------------
-+ * physical |G|G|B|G|B|B|G|G|G|G|B|G|B|
-+ * ---------------------------
-+ * What bb_tbl[i] looks like:
-+ * physical block(i):
-+ * 0 1 2 3 4 5 6 7 8 9 a b c
-+ * mapped block(bb_tbl[i]):
-+ * 0 1 3 6 7 8 9 b ......
-+ * ATTENTION:
-+ * If new bad block ocurred(n), search bmt_tbl to find
-+ * a available block(x), and fill in the bb_tbl[n] = x;
-+ */
-+ for (i = 1; i < bmtd.pool_lba; i++) {
-+ bbt->bb_tbl[i] = find_valid_block(bbt->bb_tbl[i - 1] + 1);
-+ BBT_LOG("bb_tbl[0x%x] = 0x%x", i, bbt->bb_tbl[i]);
-+ if (bbt->bb_tbl[i] == 0)
-+ return -1;
-+ }
-+
-+ /* Physical Block start Address of BMT pool */
-+ bmtd.pool_pba = bbt->bb_tbl[i - 1] + 1;
-+ if (bmtd.pool_pba >= bmtd.total_blks - 2) {
-+ pr_info("nand: FATAL ERR: Too many bad blocks!!\n");
-+ return -1;
-+ }
-+
-+ BBT_LOG("pool_pba=0x%x", bmtd.pool_pba);
-+ i = 0;
-+ block = bmtd.pool_pba;
-+ /*
-+ * The bmt table is used for runtime bad block mapping
-+ * G - Good block; B - Bad block
-+ * ---------------------------
-+ * physical |G|G|B|G|B|B|G|G|G|G|B|G|B|
-+ * ---------------------------
-+ * block: 0 1 2 3 4 5 6 7 8 9 a b c
-+ * What bmt_tbl[i] looks like in initial state:
-+ * i:
-+ * 0 1 2 3 4 5 6 7
-+ * bmt_tbl[i].block:
-+ * 0 1 3 6 7 8 9 b
-+ * bmt_tbl[i].mapped:
-+ * N N N N N N N B
-+ * N - Not mapped(Available)
-+ * M - Mapped
-+ * B - BMT
-+ * ATTENTION:
-+ * BMT always in the last valid block in pool
-+ */
-+ while ((block = find_valid_block(block)) != 0) {
-+ bbt->bmt_tbl[i].block = block;
-+ bbt->bmt_tbl[i].mapped = NO_MAPPED;
-+ BBT_LOG("bmt_tbl[%d].block = 0x%x", i, block);
-+ block++;
-+ i++;
-+ }
-+
-+ /* i - How many available blocks in pool, which is the length of bmt_tbl[]
-+ * bmtd.bmt_blk_idx - bmt_tbl[bmtd.bmt_blk_idx].block => the BMT block
-+ */
-+ bmtd.bmt_blk_idx = i - 1;
-+ bbt->bmt_tbl[bmtd.bmt_blk_idx].mapped = BMT_MAPPED;
-+
-+ if (i < 1) {
-+ pr_info("nand: FATAL ERR: no space to store BMT!!\n");
-+ return -1;
-+ }
-+
-+ pr_info("[BBT] %d available blocks in BMT pool\n", i);
-+
-+ return 0;
-+}
-+
-+static bool is_valid_bmt(unsigned char *buf, unsigned char *fdm)
-+{
-+ struct bbbt *bbt = (struct bbbt *)buf;
-+ u8 *sig = (u8*)bbt->signature + MAIN_SIGNATURE_OFFSET;
-+
-+
-+ if (memcmp(bbt->signature + MAIN_SIGNATURE_OFFSET, "BMT", 3) == 0 &&
-+ memcmp(fdm + OOB_SIGNATURE_OFFSET, "bmt", 3) == 0) {
-+ if (bbt->version == BBMT_VERSION)
-+ return true;
-+ }
-+ BBT_LOG("[BBT] BMT Version not match,upgrage preloader and uboot please! sig=%02x%02x%02x, fdm=%02x%02x%02x",
-+ sig[0], sig[1], sig[2],
-+ fdm[1], fdm[2], fdm[3]);
-+ return false;
-+}
-+
-+static u16 get_bmt_index(struct bbmt *bmt)
-+{
-+ int i = 0;
-+
-+ while (bmt[i].block != BMT_TBL_DEF_VAL) {
-+ if (bmt[i].mapped == BMT_MAPPED)
-+ return i;
-+ i++;
-+ }
-+ return 0;
-+}
-+
-+static struct bbbt *scan_bmt(u16 block)
-+{
-+ u8 fdm[4];
-+
-+ if (block < bmtd.pool_lba)
-+ return NULL;
-+
-+ if (read_bmt(block, nand_bbt_buf, fdm, sizeof(fdm)))
-+ return scan_bmt(block - 1);
-+
-+ if (is_valid_bmt(nand_bbt_buf, fdm)) {
-+ bmtd.bmt_blk_idx = get_bmt_index(((struct bbbt *)nand_bbt_buf)->bmt_tbl);
-+ if (bmtd.bmt_blk_idx == 0) {
-+ pr_info("[BBT] FATAL ERR: bmt block index is wrong!\n");
-+ return NULL;
-+ }
-+ pr_info("[BBT] BMT.v2 is found at 0x%x\n", block);
-+ return (struct bbbt *)nand_bbt_buf;
-+ } else
-+ return scan_bmt(block - 1);
-+}
-+
-+/* Write the Burner Bad Block Table to Nand Flash
-+ * n - write BMT to bmt_tbl[n]
-+ */
-+static u16 upload_bmt(struct bbbt *bbt, int n)
-+{
-+ u16 block;
-+
-+retry:
-+ if (n < 0 || bbt->bmt_tbl[n].mapped == NORMAL_MAPPED) {
-+ pr_info("nand: FATAL ERR: no space to store BMT!\n");
-+ return (u16)-1;
-+ }
-+
-+ block = bbt->bmt_tbl[n].block;
-+ BBT_LOG("n = 0x%x, block = 0x%x", n, block);
-+ if (bbt_nand_erase(block)) {
-+ bbt->bmt_tbl[n].block = 0;
-+ /* erase failed, try the previous block: bmt_tbl[n - 1].block */
-+ n--;
-+ goto retry;
-+ }
-+
-+ /* The signature offset is fixed set to 0,
-+ * oob signature offset is fixed set to 1
-+ */
-+ memcpy(bbt->signature + MAIN_SIGNATURE_OFFSET, "BMT", 3);
-+ bbt->version = BBMT_VERSION;
-+
-+ if (write_bmt(block, (unsigned char *)bbt)) {
-+ bbt->bmt_tbl[n].block = 0;
-+
-+ /* write failed, try the previous block in bmt_tbl[n - 1] */
-+ n--;
-+ goto retry;
-+ }
-+
-+ /* Return the current index(n) of BMT pool (bmt_tbl[n]) */
-+ return n;
-+}
-+
-+static u16 find_valid_block_in_pool(struct bbbt *bbt)
-+{
-+ int i;
-+
-+ if (bmtd.bmt_blk_idx == 0)
-+ goto error;
-+
-+ for (i = 0; i < bmtd.bmt_blk_idx; i++) {
-+ if (bbt->bmt_tbl[i].block != 0 && bbt->bmt_tbl[i].mapped == NO_MAPPED) {
-+ bbt->bmt_tbl[i].mapped = NORMAL_MAPPED;
-+ return bbt->bmt_tbl[i].block;
-+ }
-+ }
-+
-+error:
-+ pr_info("nand: FATAL ERR: BMT pool is run out!\n");
-+ return 0;
-+}
-+
-+/* We met a bad block, mark it as bad and map it to a valid block in pool,
-+ * if it's a write failure, we need to write the data to mapped block
-+ */
-+static bool update_bmt(u16 block)
-+{
-+ u16 mapped_blk;
-+ struct bbbt *bbt;
-+
-+ bbt = bmtd.bbt;
-+ mapped_blk = find_valid_block_in_pool(bbt);
-+ if (mapped_blk == 0)
-+ return false;
-+
-+ /* Map new bad block to available block in pool */
-+ bbt->bb_tbl[block] = mapped_blk;
-+ bmtd.bmt_blk_idx = upload_bmt(bbt, bmtd.bmt_blk_idx);
-+
-+ return true;
-+}
-+
-+u16 get_mapping_block_index(int block)
-+{
-+ int mapping_block;
-+
-+ if (block < bmtd.pool_lba)
-+ mapping_block = bmtd.bbt->bb_tbl[block];
-+ else
-+ mapping_block = block;
-+ BBT_LOG("0x%x mapped to 0x%x", block, mapping_block);
-+
-+ return mapping_block;
-+}
-+
-+static int
-+mtk_bmt_read(struct mtd_info *mtd, loff_t from,
-+ struct mtd_oob_ops *ops)
-+{
-+ struct mtd_oob_ops cur_ops = *ops;
-+ int retry_count = 0;
-+ loff_t cur_from;
-+ int ret;
-+
-+ ops->retlen = 0;
-+ ops->oobretlen = 0;
-+
-+ while (ops->retlen < ops->len || ops->oobretlen < ops->ooblen) {
-+ u32 offset = from & (bmtd.blk_size - 1);
-+ u32 block = from >> bmtd.blk_shift;
-+ u32 cur_block;
-+
-+ cur_block = get_mapping_block_index(block);
-+ cur_from = ((loff_t)cur_block << bmtd.blk_shift) + offset;
-+
-+ cur_ops.oobretlen = 0;
-+ cur_ops.retlen = 0;
-+ cur_ops.len = min_t(u32, mtd->erasesize - offset,
-+ ops->len - ops->retlen);
-+ ret = bmtd._read_oob(mtd, cur_from, &cur_ops);
-+ if (ret < 0) {
-+ update_bmt(block);
-+ if (retry_count++ < 10)
-+ continue;
-+
-+ return ret;
-+ }
-+
-+ ops->retlen += cur_ops.retlen;
-+ ops->oobretlen += cur_ops.oobretlen;
-+
-+ cur_ops.datbuf += cur_ops.retlen;
-+ cur_ops.oobbuf += cur_ops.oobretlen;
-+ cur_ops.ooblen -= cur_ops.oobretlen;
-+
-+ if (!cur_ops.len)
-+ cur_ops.len = mtd->erasesize - offset;
-+
-+ from += cur_ops.len;
-+ retry_count = 0;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+mtk_bmt_write(struct mtd_info *mtd, loff_t to,
-+ struct mtd_oob_ops *ops)
-+{
-+ struct mtd_oob_ops cur_ops = *ops;
-+ int retry_count = 0;
-+ loff_t cur_to;
-+ int ret;
-+
-+ ops->retlen = 0;
-+ ops->oobretlen = 0;
-+
-+ while (ops->retlen < ops->len || ops->oobretlen < ops->ooblen) {
-+ u32 offset = to & (bmtd.blk_size - 1);
-+ u32 block = to >> bmtd.blk_shift;
-+ u32 cur_block;
-+
-+ cur_block = get_mapping_block_index(block);
-+ cur_to = ((loff_t)cur_block << bmtd.blk_shift) + offset;
-+
-+ cur_ops.oobretlen = 0;
-+ cur_ops.retlen = 0;
-+ cur_ops.len = min_t(u32, bmtd.blk_size - offset,
-+ ops->len - ops->retlen);
-+ ret = bmtd._write_oob(mtd, cur_to, &cur_ops);
-+ if (ret < 0) {
-+ update_bmt(block);
-+ if (retry_count++ < 10)
-+ continue;
-+
-+ return ret;
-+ }
-+
-+ ops->retlen += cur_ops.retlen;
-+ ops->oobretlen += cur_ops.oobretlen;
-+
-+ cur_ops.datbuf += cur_ops.retlen;
-+ cur_ops.oobbuf += cur_ops.oobretlen;
-+ cur_ops.ooblen -= cur_ops.oobretlen;
-+
-+ if (!cur_ops.len)
-+ cur_ops.len = mtd->erasesize - offset;
-+
-+ to += cur_ops.len;
-+ retry_count = 0;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+static int
-+mtk_bmt_erase(struct nand_device *nand, const struct nand_pos *pos)
-+{
-+ struct nand_pos new_pos = *pos;
-+ int retry_count = 0;
-+ int ret;
-+
-+retry:
-+ new_pos.eraseblock = get_mapping_block_index(pos->eraseblock);
-+
-+ ret = bmtd.nand_ops->erase(nand, &new_pos);
-+ if (ret) {
-+ update_bmt(pos->eraseblock);
-+ if (retry_count++ < 10)
-+ goto retry;
-+ }
-+
-+ return ret;
-+}
-+
-+static bool
-+mtk_bmt_isbad(struct nand_device *nand, const struct nand_pos *pos)
-+{
-+ struct nand_pos new_pos = *pos;
-+ int retry_count = 0;
-+ bool ret;
-+
-+retry:
-+ new_pos.eraseblock = get_mapping_block_index(pos->eraseblock);
-+
-+ ret = bmtd.nand_ops->isbad(nand, &new_pos);
-+ if (ret) {
-+ update_bmt(pos->eraseblock);
-+ if (retry_count++ < 10)
-+ goto retry;
-+ }
-+
-+ return ret;
-+}
-+
-+static int
-+mtk_bmt_markbad(struct nand_device *nand, const struct nand_pos *pos)
-+{
-+ struct nand_pos new_pos = *pos;
-+
-+ new_pos.eraseblock = get_mapping_block_index(new_pos.eraseblock);
-+ update_bmt(pos->eraseblock);
-+
-+ return bmtd.nand_ops->markbad(nand, &new_pos);
-+}
-+
-+static void
-+mtk_bmt_replace_ops(struct mtd_info *mtd)
-+{
-+ static const struct nand_ops mtk_bmt_nand_ops = {
-+ .erase = mtk_bmt_erase,
-+ .isbad = mtk_bmt_isbad,
-+ .markbad = mtk_bmt_markbad,
-+ };
-+ struct nand_device *nand = mtd_to_nanddev(mtd);
-+
-+ bmtd.nand_ops = nand->ops;
-+ bmtd._read_oob = mtd->_read_oob;
-+ bmtd._write_oob = mtd->_write_oob;
-+
-+ mtd->_read_oob = mtk_bmt_read;
-+ mtd->_write_oob = mtk_bmt_write;
-+ nand->ops = &mtk_bmt_nand_ops;
-+}
-+
-+static int mtk_bmt_debug_mark_good(void *data, u64 val)
-+{
-+ u32 block = val >> bmtd.blk_shift;
-+
-+ bmtd.bbt->bb_tbl[block] = block;
-+ bmtd.bmt_blk_idx = upload_bmt(bmtd.bbt, bmtd.bmt_blk_idx);
-+
-+ return 0;
-+}
-+
-+static int mtk_bmt_debug_mark_bad(void *data, u64 val)
-+{
-+ u32 block = val >> bmtd.blk_shift;
-+
-+ update_bmt(block);
-+
-+ return 0;
-+}
-+
-+DEFINE_DEBUGFS_ATTRIBUTE(fops_mark_good, NULL, mtk_bmt_debug_mark_good, "%llu\n");
-+DEFINE_DEBUGFS_ATTRIBUTE(fops_mark_bad, NULL, mtk_bmt_debug_mark_bad, "%llu\n");
-+
-+static void
-+mtk_bmt_add_debugfs(void)
-+{
-+ struct dentry *dir;
-+
-+ dir = bmtd.debugfs_dir = debugfs_create_dir("mtk-bmt", NULL);
-+ if (!dir)
-+ return;
-+
-+ debugfs_create_file_unsafe("mark_good", S_IWUSR, dir, NULL, &fops_mark_good);
-+ debugfs_create_file_unsafe("mark_bad", S_IWUSR, dir, NULL, &fops_mark_bad);
-+}
-+
-+void mtk_bmt_detach(struct mtd_info *mtd)
-+{
-+ struct nand_device *nand = mtd_to_nanddev(mtd);
-+
-+ if (bmtd.mtd != mtd)
-+ return;
-+
-+ if (bmtd.debugfs_dir)
-+ debugfs_remove_recursive(bmtd.debugfs_dir);
-+ bmtd.debugfs_dir = NULL;
-+
-+ kfree(nand_bbt_buf);
-+ kfree(nand_data_buf);
-+
-+ mtd->_read_oob = bmtd._read_oob;
-+ mtd->_write_oob = bmtd._write_oob;
-+ mtd->size = bmtd.total_blks << bmtd.blk_shift;
-+ nand->ops = bmtd.nand_ops;
-+
-+ memset(&bmtd, 0, sizeof(bmtd));
-+}
-+
-+/* total_blocks - The total count of blocks that the Nand Chip has */
-+int mtk_bmt_attach(struct mtd_info *mtd)
-+{
-+ struct device_node *np;
-+ struct bbbt *bbt;
-+ u32 bufsz;
-+ u32 block;
-+ u16 total_blocks, pmt_block;
-+ int ret = 0;
-+ u32 bmt_pool_size;
-+
-+ if (bmtd.mtd)
-+ return -ENOSPC;
-+
-+ np = mtd_get_of_node(mtd);
-+ if (!np)
-+ return 0;
-+
-+ if (!of_property_read_bool(np, "mediatek,bmt-v2"))
-+ return 0;
-+
-+ if (of_property_read_u32(np, "mediatek,bmt-pool-size",
-+ &bmt_pool_size) != 0)
-+ bmt_pool_size = 80;
-+
-+ if (of_property_read_u8(np, "mediatek,bmt-oob-offset",
-+ &bmtd.oob_offset) != 0)
-+ bmtd.oob_offset = 8;
-+
-+ bmtd.mtd = mtd;
-+ mtk_bmt_replace_ops(mtd);
-+
-+ bmtd.blk_size = mtd->erasesize;
-+ bmtd.blk_shift = ffs(bmtd.blk_size) - 1;
-+ bmtd.pg_size = mtd->writesize;
-+ bmtd.pg_shift = ffs(bmtd.pg_size) - 1;
-+ total_blocks = mtd->size >> bmtd.blk_shift;
-+ pmt_block = total_blocks - bmt_pool_size - 2;
-+
-+ mtd->size = pmt_block << bmtd.blk_shift;
-+
-+ /*
-+ * ---------------------------------------
-+ * | PMT(2blks) | BMT POOL(totalblks * 2%) |
-+ * ---------------------------------------
-+ * ^ ^
-+ * | |
-+ * pmt_block pmt_block + 2blocks(pool_lba)
-+ *
-+ * ATTETION!!!!!!
-+ * The blocks ahead of the boundary block are stored in bb_tbl
-+ * and blocks behind are stored in bmt_tbl
-+ */
-+
-+ bmtd.pool_lba = (u16)(pmt_block + 2);
-+ bmtd.total_blks = total_blocks;
-+ bmtd.bb_max = bmtd.total_blks * BBPOOL_RATIO / 100;
-+
-+ /* 3 buffers we need */
-+ bufsz = round_up(sizeof(struct bbbt), bmtd.pg_size);
-+ bmtd.bmt_pgs = bufsz >> bmtd.pg_shift;
-+
-+ nand_bbt_buf = kzalloc(bufsz, GFP_KERNEL);
-+ nand_data_buf = kzalloc(bmtd.pg_size, GFP_KERNEL);
-+
-+ if (!nand_bbt_buf || !nand_data_buf) {
-+ pr_info("nand: FATAL ERR: allocate buffer failed!\n");
-+ ret = -1;
-+ goto error;
-+ }
-+
-+ memset(nand_bbt_buf, 0xff, bufsz);
-+ memset(nand_data_buf, 0xff, bmtd.pg_size);
-+
-+ BBT_LOG("bbtbuf=0x%p(0x%x) dat=0x%p(0x%x)",
-+ nand_bbt_buf, bufsz, nand_data_buf, bmtd.pg_size);
-+ BBT_LOG("pool_lba=0x%x total_blks=0x%x bb_max=0x%x",
-+ bmtd.pool_lba, bmtd.total_blks, bmtd.bb_max);
-+
-+ /* Scanning start from the first page of the last block
-+ * of whole flash
-+ */
-+ bbt = scan_bmt(bmtd.total_blks - 1);
-+ if (!bbt) {
-+ /* BMT not found */
-+ if (bmtd.total_blks > BB_TABLE_MAX + BMT_TABLE_MAX) {
-+ pr_info("nand: FATAL: Too many blocks, can not support!\n");
-+ ret = -1;
-+ goto error;
-+ }
-+
-+ bbt = (struct bbbt *)nand_bbt_buf;
-+ memset(bbt->bmt_tbl, BMT_TBL_DEF_VAL, sizeof(bbt->bmt_tbl));
-+
-+ if (scan_bad_blocks(bbt)) {
-+ ret = -1;
-+ goto error;
-+ }
-+
-+ /* BMT always in the last valid block in pool */
-+ bmtd.bmt_blk_idx = upload_bmt(bbt, bmtd.bmt_blk_idx);
-+ block = bbt->bmt_tbl[bmtd.bmt_blk_idx].block;
-+ pr_notice("[BBT] BMT.v2 is written into PBA:0x%x\n", block);
-+
-+ if (bmtd.bmt_blk_idx == 0)
-+ pr_info("nand: Warning: no available block in BMT pool!\n");
-+ else if (bmtd.bmt_blk_idx == (u16)-1) {
-+ ret = -1;
-+ goto error;
-+ }
-+ }
-+ mtk_bmt_add_debugfs();
-+
-+ bmtd.bbt = bbt;
-+ return 0;
-+
-+error:
-+ mtk_bmt_detach(mtd);
-+ return ret;
-+}
-+
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Xiangsheng Hou <xiangsheng.hou@mediatek.com>, Felix Fietkau <nbd@nbd.name>");
-+MODULE_DESCRIPTION("Bad Block mapping management v2 for MediaTek NAND Flash Driver");
-+
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -18,6 +18,7 @@
- #include <linux/slab.h>
- #include <linux/spi/spi.h>
- #include <linux/spi/spi-mem.h>
-+#include <linux/mtd/mtk_bmt.h>
-
- static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val)
- {
-@@ -1100,6 +1101,8 @@ static int spinand_probe(struct spi_mem
- if (ret)
- return ret;
-
-+ mtk_bmt_attach(mtd);
-+
- ret = mtd_device_register(mtd, NULL, 0);
- if (ret)
- goto err_spinand_cleanup;
-@@ -1125,6 +1128,7 @@ static int spinand_remove(struct spi_mem
- if (ret)
- return ret;
-
-+ mtk_bmt_detach(mtd);
- spinand_cleanup(spinand);
-
- return 0;
---- /dev/null
-+++ b/include/linux/mtd/mtk_bmt.h
-@@ -0,0 +1,18 @@
-+#ifndef __MTK_BMT_H
-+#define __MTK_BMT_H
-+
-+#ifdef CONFIG_MTD_NAND_MTK_BMT
-+int mtk_bmt_attach(struct mtd_info *mtd);
-+void mtk_bmt_detach(struct mtd_info *mtd);
-+#else
-+static inline int mtk_bmt_attach(struct mtd_info *mtd)
-+{
-+ return 0;
-+}
-+
-+static inline void mtk_bmt_detach(struct mtd_info *mtd)
-+{
-+}
-+#endif
-+
-+#endif
diff --git a/target/linux/mediatek/patches-5.4/0350-mtd-parsers-trx-Allow-to-specify-trx-magic-in-DT.patch b/target/linux/mediatek/patches-5.4/0350-mtd-parsers-trx-Allow-to-specify-trx-magic-in-DT.patch
deleted file mode 100644
index 0446ce9386..0000000000
--- a/target/linux/mediatek/patches-5.4/0350-mtd-parsers-trx-Allow-to-specify-trx-magic-in-DT.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 0600e3d81628002a5cd80cf83ee454851b0063c0 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Sun, 7 Mar 2021 18:19:26 +0100
-Subject: mtd: parsers: trx: Allow to specify brcm,trx-magic in DT
-
-Buffalo uses a different TRX magic for every device, to be able to use
-this trx parser, make it possible to specify the TRX magic in device
-tree. If no TRX magic is specified in device tree, the standard value
-will be used. This value should only be specified if a vendor chooses to
-use a non standard TRX magic.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- .../bindings/mtd/partitions/brcm,trx.txt | 5 +++++
- drivers/mtd/parsers/parser_trx.c | 21 ++++++++++++++++++-
- 2 files changed, 25 insertions(+), 1 deletion(-)
-
---- a/Documentation/devicetree/bindings/mtd/partitions/brcm,trx.txt
-+++ b/Documentation/devicetree/bindings/mtd/partitions/brcm,trx.txt
-@@ -28,6 +28,11 @@ detected by a software parsing TRX heade
- Required properties:
- - compatible : (required) must be "brcm,trx"
-
-+Optional properties:
-+
-+- brcm,trx-magic: TRX magic, if it is different from the default magic
-+ 0x30524448 as a u32.
-+
- Example:
-
- flash@0 {
---- a/drivers/mtd/parsers/parser_trx.c
-+++ b/drivers/mtd/parsers/parser_trx.c
-@@ -74,6 +74,24 @@ out_default:
- return "rootfs";
- }
-
-+static uint32_t parser_trx_get_magic(struct mtd_info *mtd)
-+{
-+ uint32_t trx_magic = TRX_MAGIC;
-+ struct device_node *np;
-+ int err;
-+
-+ np = mtd_get_of_node(mtd);
-+ if (!np)
-+ return trx_magic;
-+
-+ /* Get different magic from device tree if specified */
-+ err = of_property_read_u32(np, "brcm,trx-magic", &trx_magic);
-+ if (err != 0 && err != -EINVAL)
-+ pr_err("failed to parse \"brcm,trx-magic\" DT attribute, use default: %d\n", err);
-+
-+ return trx_magic;
-+}
-+
- static int parser_trx_parse(struct mtd_info *mtd,
- const struct mtd_partition **pparts,
- struct mtd_part_parser_data *data)
-@@ -83,6 +101,7 @@ static int parser_trx_parse(struct mtd_i
- struct trx_header trx;
- size_t bytes_read;
- uint8_t curr_part = 0, i = 0;
-+ uint32_t trx_magic = parser_trx_get_magic(mtd);
- int err;
-
- parts = kcalloc(TRX_PARSER_MAX_PARTS, sizeof(struct mtd_partition),
-@@ -97,7 +116,7 @@ static int parser_trx_parse(struct mtd_i
- return err;
- }
-
-- if (trx.magic != TRX_MAGIC) {
-+ if (trx.magic != trx_magic) {
- kfree(parts);
- return -ENOENT;
- }
diff --git a/target/linux/mediatek/patches-5.4/0351-mtd-parsers-Remove-dependency-to-BRCM-architectures.patch b/target/linux/mediatek/patches-5.4/0351-mtd-parsers-Remove-dependency-to-BRCM-architectures.patch
deleted file mode 100644
index fa94c22304..0000000000
--- a/target/linux/mediatek/patches-5.4/0351-mtd-parsers-Remove-dependency-to-BRCM-architectures.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 63f0cf88ab5461acb0911252f12bb94ee3bf05a2 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Sun, 7 Mar 2021 18:23:29 +0100
-Subject: mtd: parsers: Remove dependency to BRCM architectures
-
-Buffalo uses the TRX partition format also on Mediatek SoCs.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/mtd/parsers/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/mtd/parsers/Kconfig
-+++ b/drivers/mtd/parsers/Kconfig
-@@ -131,7 +131,7 @@ config MTD_AFS_PARTS
-
- config MTD_PARSER_TRX
- tristate "Parser for TRX format partitions"
-- depends on MTD && (BCM47XX || ARCH_BCM_5301X || COMPILE_TEST)
-+ depends on MTD
- help
- TRX is a firmware format used by Broadcom on their devices. It
- may contain up to 3/4 partitions (depending on the version).
diff --git a/target/linux/mediatek/patches-5.4/0500-v5.6-crypto-backport-inside-secure.patch b/target/linux/mediatek/patches-5.4/0500-v5.6-crypto-backport-inside-secure.patch
deleted file mode 100644
index 2fae90ef9e..0000000000
--- a/target/linux/mediatek/patches-5.4/0500-v5.6-crypto-backport-inside-secure.patch
+++ /dev/null
@@ -1,5464 +0,0 @@
---- a/drivers/crypto/inside-secure/safexcel.c
-+++ b/drivers/crypto/inside-secure/safexcel.c
-@@ -75,9 +75,9 @@ static void eip197_trc_cache_banksel(str
- }
-
- static u32 eip197_trc_cache_probe(struct safexcel_crypto_priv *priv,
-- int maxbanks, u32 probemask)
-+ int maxbanks, u32 probemask, u32 stride)
- {
-- u32 val, addrhi, addrlo, addrmid;
-+ u32 val, addrhi, addrlo, addrmid, addralias, delta, marker;
- int actbank;
-
- /*
-@@ -87,32 +87,37 @@ static u32 eip197_trc_cache_probe(struct
- addrhi = 1 << (16 + maxbanks);
- addrlo = 0;
- actbank = min(maxbanks - 1, 0);
-- while ((addrhi - addrlo) > 32) {
-+ while ((addrhi - addrlo) > stride) {
- /* write marker to lowest address in top half */
- addrmid = (addrhi + addrlo) >> 1;
-+ marker = (addrmid ^ 0xabadbabe) & probemask; /* Unique */
- eip197_trc_cache_banksel(priv, addrmid, &actbank);
-- writel((addrmid | (addrlo << 16)) & probemask,
-+ writel(marker,
- priv->base + EIP197_CLASSIFICATION_RAMS +
- (addrmid & 0xffff));
-
-- /* write marker to lowest address in bottom half */
-- eip197_trc_cache_banksel(priv, addrlo, &actbank);
-- writel((addrlo | (addrhi << 16)) & probemask,
-- priv->base + EIP197_CLASSIFICATION_RAMS +
-- (addrlo & 0xffff));
-+ /* write invalid markers to possible aliases */
-+ delta = 1 << __fls(addrmid);
-+ while (delta >= stride) {
-+ addralias = addrmid - delta;
-+ eip197_trc_cache_banksel(priv, addralias, &actbank);
-+ writel(~marker,
-+ priv->base + EIP197_CLASSIFICATION_RAMS +
-+ (addralias & 0xffff));
-+ delta >>= 1;
-+ }
-
- /* read back marker from top half */
- eip197_trc_cache_banksel(priv, addrmid, &actbank);
- val = readl(priv->base + EIP197_CLASSIFICATION_RAMS +
- (addrmid & 0xffff));
-
-- if (val == ((addrmid | (addrlo << 16)) & probemask)) {
-+ if ((val & probemask) == marker)
- /* read back correct, continue with top half */
- addrlo = addrmid;
-- } else {
-+ else
- /* not read back correct, continue with bottom half */
- addrhi = addrmid;
-- }
- }
- return addrhi;
- }
-@@ -150,7 +155,7 @@ static void eip197_trc_cache_clear(struc
- htable_offset + i * sizeof(u32));
- }
-
--static void eip197_trc_cache_init(struct safexcel_crypto_priv *priv)
-+static int eip197_trc_cache_init(struct safexcel_crypto_priv *priv)
- {
- u32 val, dsize, asize;
- int cs_rc_max, cs_ht_wc, cs_trc_rec_wc, cs_trc_lg_rec_wc;
-@@ -183,7 +188,7 @@ static void eip197_trc_cache_init(struct
- writel(val, priv->base + EIP197_TRC_PARAMS);
-
- /* Probed data RAM size in bytes */
-- dsize = eip197_trc_cache_probe(priv, maxbanks, 0xffffffff);
-+ dsize = eip197_trc_cache_probe(priv, maxbanks, 0xffffffff, 32);
-
- /*
- * Now probe the administration RAM size pretty much the same way
-@@ -196,11 +201,18 @@ static void eip197_trc_cache_init(struct
- writel(val, priv->base + EIP197_TRC_PARAMS);
-
- /* Probed admin RAM size in admin words */
-- asize = eip197_trc_cache_probe(priv, 0, 0xbfffffff) >> 4;
-+ asize = eip197_trc_cache_probe(priv, 0, 0x3fffffff, 16) >> 4;
-
- /* Clear any ECC errors detected while probing! */
- writel(0, priv->base + EIP197_TRC_ECCCTRL);
-
-+ /* Sanity check probing results */
-+ if (dsize < EIP197_MIN_DSIZE || asize < EIP197_MIN_ASIZE) {
-+ dev_err(priv->dev, "Record cache probing failed (%d,%d).",
-+ dsize, asize);
-+ return -ENODEV;
-+ }
-+
- /*
- * Determine optimal configuration from RAM sizes
- * Note that we assume that the physical RAM configuration is sane
-@@ -251,6 +263,7 @@ static void eip197_trc_cache_init(struct
-
- dev_info(priv->dev, "TRC init: %dd,%da (%dr,%dh)\n",
- dsize, asize, cs_rc_max, cs_ht_wc + cs_ht_wc);
-+ return 0;
- }
-
- static void eip197_init_firmware(struct safexcel_crypto_priv *priv)
-@@ -298,13 +311,14 @@ static void eip197_init_firmware(struct
- static int eip197_write_firmware(struct safexcel_crypto_priv *priv,
- const struct firmware *fw)
- {
-- const u32 *data = (const u32 *)fw->data;
-+ const __be32 *data = (const __be32 *)fw->data;
- int i;
-
- /* Write the firmware */
- for (i = 0; i < fw->size / sizeof(u32); i++)
- writel(be32_to_cpu(data[i]),
-- priv->base + EIP197_CLASSIFICATION_RAMS + i * sizeof(u32));
-+ priv->base + EIP197_CLASSIFICATION_RAMS +
-+ i * sizeof(__be32));
-
- /* Exclude final 2 NOPs from size */
- return i - EIP197_FW_TERMINAL_NOPS;
-@@ -471,6 +485,14 @@ static int safexcel_hw_setup_cdesc_rings
- cd_fetch_cnt = ((1 << priv->hwconfig.hwcfsize) /
- cd_size_rnd) - 1;
- }
-+ /*
-+ * Since we're using command desc's way larger than formally specified,
-+ * we need to check whether we can fit even 1 for low-end EIP196's!
-+ */
-+ if (!cd_fetch_cnt) {
-+ dev_err(priv->dev, "Unable to fit even 1 command desc!\n");
-+ return -ENODEV;
-+ }
-
- for (i = 0; i < priv->config.rings; i++) {
- /* ring base address */
-@@ -479,12 +501,12 @@ static int safexcel_hw_setup_cdesc_rings
- writel(upper_32_bits(priv->ring[i].cdr.base_dma),
- EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_RING_BASE_ADDR_HI);
-
-- writel(EIP197_xDR_DESC_MODE_64BIT | (priv->config.cd_offset << 16) |
-- priv->config.cd_size,
-+ writel(EIP197_xDR_DESC_MODE_64BIT | EIP197_CDR_DESC_MODE_ADCP |
-+ (priv->config.cd_offset << 14) | priv->config.cd_size,
- EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_DESC_SIZE);
- writel(((cd_fetch_cnt *
- (cd_size_rnd << priv->hwconfig.hwdataw)) << 16) |
-- (cd_fetch_cnt * priv->config.cd_offset),
-+ (cd_fetch_cnt * (priv->config.cd_offset / sizeof(u32))),
- EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_CFG);
-
- /* Configure DMA tx control */
-@@ -527,13 +549,13 @@ static int safexcel_hw_setup_rdesc_rings
- writel(upper_32_bits(priv->ring[i].rdr.base_dma),
- EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_RING_BASE_ADDR_HI);
-
-- writel(EIP197_xDR_DESC_MODE_64BIT | (priv->config.rd_offset << 16) |
-+ writel(EIP197_xDR_DESC_MODE_64BIT | (priv->config.rd_offset << 14) |
- priv->config.rd_size,
- EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_DESC_SIZE);
-
- writel(((rd_fetch_cnt *
- (rd_size_rnd << priv->hwconfig.hwdataw)) << 16) |
-- (rd_fetch_cnt * priv->config.rd_offset),
-+ (rd_fetch_cnt * (priv->config.rd_offset / sizeof(u32))),
- EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_CFG);
-
- /* Configure DMA tx control */
-@@ -559,7 +581,7 @@ static int safexcel_hw_setup_rdesc_rings
- static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
- {
- u32 val;
-- int i, ret, pe;
-+ int i, ret, pe, opbuflo, opbufhi;
-
- dev_dbg(priv->dev, "HW init: using %d pipe(s) and %d ring(s)\n",
- priv->config.pes, priv->config.rings);
-@@ -595,8 +617,8 @@ static int safexcel_hw_init(struct safex
- writel(EIP197_DxE_THR_CTRL_RESET_PE,
- EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL(pe));
-
-- if (priv->flags & SAFEXCEL_HW_EIP197)
-- /* Reset HIA input interface arbiter (EIP197 only) */
-+ if (priv->flags & EIP197_PE_ARB)
-+ /* Reset HIA input interface arbiter (if present) */
- writel(EIP197_HIA_RA_PE_CTRL_RESET,
- EIP197_HIA_AIC(priv) + EIP197_HIA_RA_PE_CTRL(pe));
-
-@@ -639,9 +661,16 @@ static int safexcel_hw_init(struct safex
- ;
-
- /* DMA transfer size to use */
-+ if (priv->hwconfig.hwnumpes > 4) {
-+ opbuflo = 9;
-+ opbufhi = 10;
-+ } else {
-+ opbuflo = 7;
-+ opbufhi = 8;
-+ }
- val = EIP197_HIA_DSE_CFG_DIS_DEBUG;
-- val |= EIP197_HIA_DxE_CFG_MIN_DATA_SIZE(7) |
-- EIP197_HIA_DxE_CFG_MAX_DATA_SIZE(8);
-+ val |= EIP197_HIA_DxE_CFG_MIN_DATA_SIZE(opbuflo) |
-+ EIP197_HIA_DxE_CFG_MAX_DATA_SIZE(opbufhi);
- val |= EIP197_HIA_DxE_CFG_DATA_CACHE_CTRL(WR_CACHE_3BITS);
- val |= EIP197_HIA_DSE_CFG_ALWAYS_BUFFERABLE;
- /* FIXME: instability issues can occur for EIP97 but disabling
-@@ -655,8 +684,8 @@ static int safexcel_hw_init(struct safex
- writel(0, EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_CTRL(pe));
-
- /* Configure the procesing engine thresholds */
-- writel(EIP197_PE_OUT_DBUF_THRES_MIN(7) |
-- EIP197_PE_OUT_DBUF_THRES_MAX(8),
-+ writel(EIP197_PE_OUT_DBUF_THRES_MIN(opbuflo) |
-+ EIP197_PE_OUT_DBUF_THRES_MAX(opbufhi),
- EIP197_PE(priv) + EIP197_PE_OUT_DBUF_THRES(pe));
-
- /* Processing Engine configuration */
-@@ -696,7 +725,7 @@ static int safexcel_hw_init(struct safex
- writel(0,
- EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_PROC_PNTR);
-
-- writel((EIP197_DEFAULT_RING_SIZE * priv->config.cd_offset) << 2,
-+ writel((EIP197_DEFAULT_RING_SIZE * priv->config.cd_offset),
- EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_RING_SIZE);
- }
-
-@@ -719,7 +748,7 @@ static int safexcel_hw_init(struct safex
- EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_PROC_PNTR);
-
- /* Ring size */
-- writel((EIP197_DEFAULT_RING_SIZE * priv->config.rd_offset) << 2,
-+ writel((EIP197_DEFAULT_RING_SIZE * priv->config.rd_offset),
- EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_RING_SIZE);
- }
-
-@@ -736,19 +765,28 @@ static int safexcel_hw_init(struct safex
- /* Clear any HIA interrupt */
- writel(GENMASK(30, 20), EIP197_HIA_AIC_G(priv) + EIP197_HIA_AIC_G_ACK);
-
-- if (priv->flags & SAFEXCEL_HW_EIP197) {
-- eip197_trc_cache_init(priv);
-- priv->flags |= EIP197_TRC_CACHE;
-+ if (priv->flags & EIP197_SIMPLE_TRC) {
-+ writel(EIP197_STRC_CONFIG_INIT |
-+ EIP197_STRC_CONFIG_LARGE_REC(EIP197_CS_TRC_REC_WC) |
-+ EIP197_STRC_CONFIG_SMALL_REC(EIP197_CS_TRC_REC_WC),
-+ priv->base + EIP197_STRC_CONFIG);
-+ writel(EIP197_PE_EIP96_TOKEN_CTRL2_CTX_DONE,
-+ EIP197_PE(priv) + EIP197_PE_EIP96_TOKEN_CTRL2(0));
-+ } else if (priv->flags & SAFEXCEL_HW_EIP197) {
-+ ret = eip197_trc_cache_init(priv);
-+ if (ret)
-+ return ret;
-+ }
-
-+ if (priv->flags & EIP197_ICE) {
- ret = eip197_load_firmwares(priv);
- if (ret)
- return ret;
- }
-
-- safexcel_hw_setup_cdesc_rings(priv);
-- safexcel_hw_setup_rdesc_rings(priv);
--
-- return 0;
-+ return safexcel_hw_setup_cdesc_rings(priv) ?:
-+ safexcel_hw_setup_rdesc_rings(priv) ?:
-+ 0;
- }
-
- /* Called with ring's lock taken */
-@@ -836,20 +874,24 @@ finalize:
- spin_unlock_bh(&priv->ring[ring].lock);
-
- /* let the RDR know we have pending descriptors */
-- writel((rdesc * priv->config.rd_offset) << 2,
-+ writel((rdesc * priv->config.rd_offset),
- EIP197_HIA_RDR(priv, ring) + EIP197_HIA_xDR_PREP_COUNT);
-
- /* let the CDR know we have pending descriptors */
-- writel((cdesc * priv->config.cd_offset) << 2,
-+ writel((cdesc * priv->config.cd_offset),
- EIP197_HIA_CDR(priv, ring) + EIP197_HIA_xDR_PREP_COUNT);
- }
-
- inline int safexcel_rdesc_check_errors(struct safexcel_crypto_priv *priv,
-- struct safexcel_result_desc *rdesc)
-+ void *rdp)
- {
-- if (likely((!rdesc->descriptor_overflow) &&
-- (!rdesc->buffer_overflow) &&
-- (!rdesc->result_data.error_code)))
-+ struct safexcel_result_desc *rdesc = rdp;
-+ struct result_data_desc *result_data = rdp + priv->config.res_offset;
-+
-+ if (likely((!rdesc->last_seg) || /* Rest only valid if last seg! */
-+ ((!rdesc->descriptor_overflow) &&
-+ (!rdesc->buffer_overflow) &&
-+ (!result_data->error_code))))
- return 0;
-
- if (rdesc->descriptor_overflow)
-@@ -858,13 +900,14 @@ inline int safexcel_rdesc_check_errors(s
- if (rdesc->buffer_overflow)
- dev_err(priv->dev, "Buffer overflow detected");
-
-- if (rdesc->result_data.error_code & 0x4066) {
-+ if (result_data->error_code & 0x4066) {
- /* Fatal error (bits 1,2,5,6 & 14) */
- dev_err(priv->dev,
- "result descriptor error (%x)",
-- rdesc->result_data.error_code);
-+ result_data->error_code);
-+
- return -EIO;
-- } else if (rdesc->result_data.error_code &
-+ } else if (result_data->error_code &
- (BIT(7) | BIT(4) | BIT(3) | BIT(0))) {
- /*
- * Give priority over authentication fails:
-@@ -872,7 +915,7 @@ inline int safexcel_rdesc_check_errors(s
- * something wrong with the input!
- */
- return -EINVAL;
-- } else if (rdesc->result_data.error_code & BIT(9)) {
-+ } else if (result_data->error_code & BIT(9)) {
- /* Authentication failed */
- return -EBADMSG;
- }
-@@ -931,16 +974,18 @@ int safexcel_invalidate_cache(struct cry
- {
- struct safexcel_command_desc *cdesc;
- struct safexcel_result_desc *rdesc;
-+ struct safexcel_token *dmmy;
- int ret = 0;
-
- /* Prepare command descriptor */
-- cdesc = safexcel_add_cdesc(priv, ring, true, true, 0, 0, 0, ctxr_dma);
-+ cdesc = safexcel_add_cdesc(priv, ring, true, true, 0, 0, 0, ctxr_dma,
-+ &dmmy);
- if (IS_ERR(cdesc))
- return PTR_ERR(cdesc);
-
- cdesc->control_data.type = EIP197_TYPE_EXTENDED;
- cdesc->control_data.options = 0;
-- cdesc->control_data.refresh = 0;
-+ cdesc->control_data.context_lo &= ~EIP197_CONTEXT_SIZE_MASK;
- cdesc->control_data.control0 = CONTEXT_CONTROL_INV_TR;
-
- /* Prepare result descriptor */
-@@ -1003,7 +1048,7 @@ handle_results:
- acknowledge:
- if (i)
- writel(EIP197_xDR_PROC_xD_PKT(i) |
-- EIP197_xDR_PROC_xD_COUNT(tot_descs * priv->config.rd_offset),
-+ (tot_descs * priv->config.rd_offset),
- EIP197_HIA_RDR(priv, ring) + EIP197_HIA_xDR_PROC_COUNT);
-
- /* If the number of requests overflowed the counter, try to proceed more
-@@ -1171,6 +1216,44 @@ static struct safexcel_alg_template *saf
- &safexcel_alg_xts_aes,
- &safexcel_alg_gcm,
- &safexcel_alg_ccm,
-+ &safexcel_alg_crc32,
-+ &safexcel_alg_cbcmac,
-+ &safexcel_alg_xcbcmac,
-+ &safexcel_alg_cmac,
-+ &safexcel_alg_chacha20,
-+ &safexcel_alg_chachapoly,
-+ &safexcel_alg_chachapoly_esp,
-+ &safexcel_alg_sm3,
-+ &safexcel_alg_hmac_sm3,
-+ &safexcel_alg_ecb_sm4,
-+ &safexcel_alg_cbc_sm4,
-+ &safexcel_alg_ofb_sm4,
-+ &safexcel_alg_cfb_sm4,
-+ &safexcel_alg_ctr_sm4,
-+ &safexcel_alg_authenc_hmac_sha1_cbc_sm4,
-+ &safexcel_alg_authenc_hmac_sm3_cbc_sm4,
-+ &safexcel_alg_authenc_hmac_sha1_ctr_sm4,
-+ &safexcel_alg_authenc_hmac_sm3_ctr_sm4,
-+ &safexcel_alg_sha3_224,
-+ &safexcel_alg_sha3_256,
-+ &safexcel_alg_sha3_384,
-+ &safexcel_alg_sha3_512,
-+ &safexcel_alg_hmac_sha3_224,
-+ &safexcel_alg_hmac_sha3_256,
-+ &safexcel_alg_hmac_sha3_384,
-+ &safexcel_alg_hmac_sha3_512,
-+ &safexcel_alg_authenc_hmac_sha1_cbc_des,
-+ &safexcel_alg_authenc_hmac_sha256_cbc_des3_ede,
-+ &safexcel_alg_authenc_hmac_sha224_cbc_des3_ede,
-+ &safexcel_alg_authenc_hmac_sha512_cbc_des3_ede,
-+ &safexcel_alg_authenc_hmac_sha384_cbc_des3_ede,
-+ &safexcel_alg_authenc_hmac_sha256_cbc_des,
-+ &safexcel_alg_authenc_hmac_sha224_cbc_des,
-+ &safexcel_alg_authenc_hmac_sha512_cbc_des,
-+ &safexcel_alg_authenc_hmac_sha384_cbc_des,
-+ &safexcel_alg_rfc4106_gcm,
-+ &safexcel_alg_rfc4543_gcm,
-+ &safexcel_alg_rfc4309_ccm,
- };
-
- static int safexcel_register_algorithms(struct safexcel_crypto_priv *priv)
-@@ -1240,30 +1323,30 @@ static void safexcel_unregister_algorith
-
- static void safexcel_configure(struct safexcel_crypto_priv *priv)
- {
-- u32 val, mask = 0;
--
-- val = readl(EIP197_HIA_AIC_G(priv) + EIP197_HIA_OPTIONS);
--
-- /* Read number of PEs from the engine */
-- if (priv->flags & SAFEXCEL_HW_EIP197)
-- /* Wider field width for all EIP197 type engines */
-- mask = EIP197_N_PES_MASK;
-- else
-- /* Narrow field width for EIP97 type engine */
-- mask = EIP97_N_PES_MASK;
--
-- priv->config.pes = (val >> EIP197_N_PES_OFFSET) & mask;
-+ u32 mask = BIT(priv->hwconfig.hwdataw) - 1;
-
-- priv->config.rings = min_t(u32, val & GENMASK(3, 0), max_rings);
-+ priv->config.pes = priv->hwconfig.hwnumpes;
-+ priv->config.rings = min_t(u32, priv->hwconfig.hwnumrings, max_rings);
-+ /* Cannot currently support more rings than we have ring AICs! */
-+ priv->config.rings = min_t(u32, priv->config.rings,
-+ priv->hwconfig.hwnumraic);
-
-- val = (val & GENMASK(27, 25)) >> 25;
-- mask = BIT(val) - 1;
--
-- priv->config.cd_size = (sizeof(struct safexcel_command_desc) / sizeof(u32));
-+ priv->config.cd_size = EIP197_CD64_FETCH_SIZE;
- priv->config.cd_offset = (priv->config.cd_size + mask) & ~mask;
-+ priv->config.cdsh_offset = (EIP197_MAX_TOKENS + mask) & ~mask;
-
-- priv->config.rd_size = (sizeof(struct safexcel_result_desc) / sizeof(u32));
-+ /* res token is behind the descr, but ofs must be rounded to buswdth */
-+ priv->config.res_offset = (EIP197_RD64_FETCH_SIZE + mask) & ~mask;
-+ /* now the size of the descr is this 1st part plus the result struct */
-+ priv->config.rd_size = priv->config.res_offset +
-+ EIP197_RD64_RESULT_SIZE;
- priv->config.rd_offset = (priv->config.rd_size + mask) & ~mask;
-+
-+ /* convert dwords to bytes */
-+ priv->config.cd_offset *= sizeof(u32);
-+ priv->config.cdsh_offset *= sizeof(u32);
-+ priv->config.rd_offset *= sizeof(u32);
-+ priv->config.res_offset *= sizeof(u32);
- }
-
- static void safexcel_init_register_offsets(struct safexcel_crypto_priv *priv)
-@@ -1309,7 +1392,7 @@ static int safexcel_probe_generic(void *
- int is_pci_dev)
- {
- struct device *dev = priv->dev;
-- u32 peid, version, mask, val, hiaopt;
-+ u32 peid, version, mask, val, hiaopt, hwopt, peopt;
- int i, ret, hwctg;
-
- priv->context_pool = dmam_pool_create("safexcel-context", dev,
-@@ -1371,13 +1454,16 @@ static int safexcel_probe_generic(void *
- */
- version = readl(EIP197_GLOBAL(priv) + EIP197_VERSION);
- if (((priv->flags & SAFEXCEL_HW_EIP197) &&
-- (EIP197_REG_LO16(version) != EIP197_VERSION_LE)) ||
-+ (EIP197_REG_LO16(version) != EIP197_VERSION_LE) &&
-+ (EIP197_REG_LO16(version) != EIP196_VERSION_LE)) ||
- ((!(priv->flags & SAFEXCEL_HW_EIP197) &&
- (EIP197_REG_LO16(version) != EIP97_VERSION_LE)))) {
- /*
- * We did not find the device that matched our initial probing
- * (or our initial probing failed) Report appropriate error.
- */
-+ dev_err(priv->dev, "Probing for EIP97/EIP19x failed - no such device (read %08x)\n",
-+ version);
- return -ENODEV;
- }
-
-@@ -1385,6 +1471,14 @@ static int safexcel_probe_generic(void *
- hwctg = version >> 28;
- peid = version & 255;
-
-+ /* Detect EIP206 processing pipe */
-+ version = readl(EIP197_PE(priv) + + EIP197_PE_VERSION(0));
-+ if (EIP197_REG_LO16(version) != EIP206_VERSION_LE) {
-+ dev_err(priv->dev, "EIP%d: EIP206 not detected\n", peid);
-+ return -ENODEV;
-+ }
-+ priv->hwconfig.ppver = EIP197_VERSION_MASK(version);
-+
- /* Detect EIP96 packet engine and version */
- version = readl(EIP197_PE(priv) + EIP197_PE_EIP96_VERSION(0));
- if (EIP197_REG_LO16(version) != EIP96_VERSION_LE) {
-@@ -1393,10 +1487,13 @@ static int safexcel_probe_generic(void *
- }
- priv->hwconfig.pever = EIP197_VERSION_MASK(version);
-
-+ hwopt = readl(EIP197_GLOBAL(priv) + EIP197_OPTIONS);
- hiaopt = readl(EIP197_HIA_AIC(priv) + EIP197_HIA_OPTIONS);
-
- if (priv->flags & SAFEXCEL_HW_EIP197) {
- /* EIP197 */
-+ peopt = readl(EIP197_PE(priv) + EIP197_PE_OPTIONS(0));
-+
- priv->hwconfig.hwdataw = (hiaopt >> EIP197_HWDATAW_OFFSET) &
- EIP197_HWDATAW_MASK;
- priv->hwconfig.hwcfsize = ((hiaopt >> EIP197_CFSIZE_OFFSET) &
-@@ -1405,6 +1502,19 @@ static int safexcel_probe_generic(void *
- priv->hwconfig.hwrfsize = ((hiaopt >> EIP197_RFSIZE_OFFSET) &
- EIP197_RFSIZE_MASK) +
- EIP197_RFSIZE_ADJUST;
-+ priv->hwconfig.hwnumpes = (hiaopt >> EIP197_N_PES_OFFSET) &
-+ EIP197_N_PES_MASK;
-+ priv->hwconfig.hwnumrings = (hiaopt >> EIP197_N_RINGS_OFFSET) &
-+ EIP197_N_RINGS_MASK;
-+ if (hiaopt & EIP197_HIA_OPT_HAS_PE_ARB)
-+ priv->flags |= EIP197_PE_ARB;
-+ if (EIP206_OPT_ICE_TYPE(peopt) == 1)
-+ priv->flags |= EIP197_ICE;
-+ /* If not a full TRC, then assume simple TRC */
-+ if (!(hwopt & EIP197_OPT_HAS_TRC))
-+ priv->flags |= EIP197_SIMPLE_TRC;
-+ /* EIP197 always has SOME form of TRC */
-+ priv->flags |= EIP197_TRC_CACHE;
- } else {
- /* EIP97 */
- priv->hwconfig.hwdataw = (hiaopt >> EIP197_HWDATAW_OFFSET) &
-@@ -1413,6 +1523,23 @@ static int safexcel_probe_generic(void *
- EIP97_CFSIZE_MASK;
- priv->hwconfig.hwrfsize = (hiaopt >> EIP97_RFSIZE_OFFSET) &
- EIP97_RFSIZE_MASK;
-+ priv->hwconfig.hwnumpes = 1; /* by definition */
-+ priv->hwconfig.hwnumrings = (hiaopt >> EIP197_N_RINGS_OFFSET) &
-+ EIP197_N_RINGS_MASK;
-+ }
-+
-+ /* Scan for ring AIC's */
-+ for (i = 0; i < EIP197_MAX_RING_AIC; i++) {
-+ version = readl(EIP197_HIA_AIC_R(priv) +
-+ EIP197_HIA_AIC_R_VERSION(i));
-+ if (EIP197_REG_LO16(version) != EIP201_VERSION_LE)
-+ break;
-+ }
-+ priv->hwconfig.hwnumraic = i;
-+ /* Low-end EIP196 may not have any ring AIC's ... */
-+ if (!priv->hwconfig.hwnumraic) {
-+ dev_err(priv->dev, "No ring interrupt controller present!\n");
-+ return -ENODEV;
- }
-
- /* Get supported algorithms from EIP96 transform engine */
-@@ -1420,10 +1547,12 @@ static int safexcel_probe_generic(void *
- EIP197_PE_EIP96_OPTIONS(0));
-
- /* Print single info line describing what we just detected */
-- dev_info(priv->dev, "EIP%d:%x(%d)-HIA:%x(%d,%d,%d),PE:%x,alg:%08x\n",
-- peid, priv->hwconfig.hwver, hwctg, priv->hwconfig.hiaver,
-- priv->hwconfig.hwdataw, priv->hwconfig.hwcfsize,
-- priv->hwconfig.hwrfsize, priv->hwconfig.pever,
-+ dev_info(priv->dev, "EIP%d:%x(%d,%d,%d,%d)-HIA:%x(%d,%d,%d),PE:%x/%x,alg:%08x\n",
-+ peid, priv->hwconfig.hwver, hwctg, priv->hwconfig.hwnumpes,
-+ priv->hwconfig.hwnumrings, priv->hwconfig.hwnumraic,
-+ priv->hwconfig.hiaver, priv->hwconfig.hwdataw,
-+ priv->hwconfig.hwcfsize, priv->hwconfig.hwrfsize,
-+ priv->hwconfig.ppver, priv->hwconfig.pever,
- priv->hwconfig.algo_flags);
-
- safexcel_configure(priv);
-@@ -1547,7 +1676,6 @@ static void safexcel_hw_reset_rings(stru
- }
- }
-
--#if IS_ENABLED(CONFIG_OF)
- /* for Device Tree platform driver */
-
- static int safexcel_probe(struct platform_device *pdev)
-@@ -1625,6 +1753,7 @@ static int safexcel_remove(struct platfo
- safexcel_unregister_algorithms(priv);
- safexcel_hw_reset_rings(priv);
-
-+ clk_disable_unprepare(priv->reg_clk);
- clk_disable_unprepare(priv->clk);
-
- for (i = 0; i < priv->config.rings; i++)
-@@ -1666,9 +1795,7 @@ static struct platform_driver crypto_sa
- .of_match_table = safexcel_of_match_table,
- },
- };
--#endif
-
--#if IS_ENABLED(CONFIG_PCI)
- /* PCIE devices - i.e. Inside Secure development boards */
-
- static int safexcel_pci_probe(struct pci_dev *pdev,
-@@ -1759,7 +1886,7 @@ static int safexcel_pci_probe(struct pci
- return rc;
- }
-
--void safexcel_pci_remove(struct pci_dev *pdev)
-+static void safexcel_pci_remove(struct pci_dev *pdev)
- {
- struct safexcel_crypto_priv *priv = pci_get_drvdata(pdev);
- int i;
-@@ -1789,54 +1916,32 @@ static struct pci_driver safexcel_pci_dr
- .probe = safexcel_pci_probe,
- .remove = safexcel_pci_remove,
- };
--#endif
--
--/* Unfortunately, we have to resort to global variables here */
--#if IS_ENABLED(CONFIG_PCI)
--int pcireg_rc = -EINVAL; /* Default safe value */
--#endif
--#if IS_ENABLED(CONFIG_OF)
--int ofreg_rc = -EINVAL; /* Default safe value */
--#endif
-
- static int __init safexcel_init(void)
- {
--#if IS_ENABLED(CONFIG_PCI)
-+ int ret;
-+
- /* Register PCI driver */
-- pcireg_rc = pci_register_driver(&safexcel_pci_driver);
--#endif
-+ ret = pci_register_driver(&safexcel_pci_driver);
-
--#if IS_ENABLED(CONFIG_OF)
- /* Register platform driver */
-- ofreg_rc = platform_driver_register(&crypto_safexcel);
-- #if IS_ENABLED(CONFIG_PCI)
-- /* Return success if either PCI or OF registered OK */
-- return pcireg_rc ? ofreg_rc : 0;
-- #else
-- return ofreg_rc;
-- #endif
--#else
-- #if IS_ENABLED(CONFIG_PCI)
-- return pcireg_rc;
-- #else
-- return -EINVAL;
-- #endif
--#endif
-+ if (IS_ENABLED(CONFIG_OF) && !ret) {
-+ ret = platform_driver_register(&crypto_safexcel);
-+ if (ret)
-+ pci_unregister_driver(&safexcel_pci_driver);
-+ }
-+
-+ return ret;
- }
-
- static void __exit safexcel_exit(void)
- {
--#if IS_ENABLED(CONFIG_OF)
- /* Unregister platform driver */
-- if (!ofreg_rc)
-+ if (IS_ENABLED(CONFIG_OF))
- platform_driver_unregister(&crypto_safexcel);
--#endif
-
--#if IS_ENABLED(CONFIG_PCI)
- /* Unregister PCI driver if successfully registered before */
-- if (!pcireg_rc)
-- pci_unregister_driver(&safexcel_pci_driver);
--#endif
-+ pci_unregister_driver(&safexcel_pci_driver);
- }
-
- module_init(safexcel_init);
---- a/drivers/crypto/inside-secure/safexcel_cipher.c
-+++ b/drivers/crypto/inside-secure/safexcel_cipher.c
-@@ -5,18 +5,22 @@
- * Antoine Tenart <antoine.tenart@free-electrons.com>
- */
-
-+#include <asm/unaligned.h>
- #include <linux/device.h>
- #include <linux/dma-mapping.h>
- #include <linux/dmapool.h>
--
- #include <crypto/aead.h>
- #include <crypto/aes.h>
- #include <crypto/authenc.h>
-+#include <crypto/chacha.h>
- #include <crypto/ctr.h>
- #include <crypto/internal/des.h>
- #include <crypto/gcm.h>
- #include <crypto/ghash.h>
-+#include <crypto/poly1305.h>
- #include <crypto/sha.h>
-+#include <crypto/sm3.h>
-+#include <crypto/sm4.h>
- #include <crypto/xts.h>
- #include <crypto/skcipher.h>
- #include <crypto/internal/aead.h>
-@@ -33,6 +37,8 @@ enum safexcel_cipher_alg {
- SAFEXCEL_DES,
- SAFEXCEL_3DES,
- SAFEXCEL_AES,
-+ SAFEXCEL_CHACHA20,
-+ SAFEXCEL_SM4,
- };
-
- struct safexcel_cipher_ctx {
-@@ -41,8 +47,12 @@ struct safexcel_cipher_ctx {
-
- u32 mode;
- enum safexcel_cipher_alg alg;
-- bool aead;
-- int xcm; /* 0=authenc, 1=GCM, 2 reserved for CCM */
-+ u8 aead; /* !=0=AEAD, 2=IPSec ESP AEAD, 3=IPsec ESP GMAC */
-+ u8 xcm; /* 0=authenc, 1=GCM, 2 reserved for CCM */
-+ u8 aadskip;
-+ u8 blocksz;
-+ u32 ivmask;
-+ u32 ctrinit;
-
- __le32 key[16];
- u32 nonce;
-@@ -51,10 +61,11 @@ struct safexcel_cipher_ctx {
- /* All the below is AEAD specific */
- u32 hash_alg;
- u32 state_sz;
-- u32 ipad[SHA512_DIGEST_SIZE / sizeof(u32)];
-- u32 opad[SHA512_DIGEST_SIZE / sizeof(u32)];
-+ __be32 ipad[SHA512_DIGEST_SIZE / sizeof(u32)];
-+ __be32 opad[SHA512_DIGEST_SIZE / sizeof(u32)];
-
- struct crypto_cipher *hkaes;
-+ struct crypto_aead *fback;
- };
-
- struct safexcel_cipher_req {
-@@ -65,206 +76,298 @@ struct safexcel_cipher_req {
- int nr_src, nr_dst;
- };
-
--static void safexcel_cipher_token(struct safexcel_cipher_ctx *ctx, u8 *iv,
-- struct safexcel_command_desc *cdesc)
-+static int safexcel_skcipher_iv(struct safexcel_cipher_ctx *ctx, u8 *iv,
-+ struct safexcel_command_desc *cdesc)
- {
-- u32 block_sz = 0;
--
- if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) {
- cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;
--
- /* 32 bit nonce */
- cdesc->control_data.token[0] = ctx->nonce;
- /* 64 bit IV part */
- memcpy(&cdesc->control_data.token[1], iv, 8);
-- /* 32 bit counter, start at 1 (big endian!) */
-- cdesc->control_data.token[3] = cpu_to_be32(1);
--
-- return;
-- } else if (ctx->xcm == EIP197_XCM_MODE_GCM) {
-- cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;
--
-- /* 96 bit IV part */
-- memcpy(&cdesc->control_data.token[0], iv, 12);
-- /* 32 bit counter, start at 1 (big endian!) */
-- cdesc->control_data.token[3] = cpu_to_be32(1);
--
-- return;
-- } else if (ctx->xcm == EIP197_XCM_MODE_CCM) {
-+ /* 32 bit counter, start at 0 or 1 (big endian!) */
-+ cdesc->control_data.token[3] =
-+ (__force u32)cpu_to_be32(ctx->ctrinit);
-+ return 4;
-+ }
-+ if (ctx->alg == SAFEXCEL_CHACHA20) {
- cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;
--
-- /* Variable length IV part */
-- memcpy(&cdesc->control_data.token[0], iv, 15 - iv[0]);
-- /* Start variable length counter at 0 */
-- memset((u8 *)&cdesc->control_data.token[0] + 15 - iv[0],
-- 0, iv[0] + 1);
--
-- return;
-+ /* 96 bit nonce part */
-+ memcpy(&cdesc->control_data.token[0], &iv[4], 12);
-+ /* 32 bit counter */
-+ cdesc->control_data.token[3] = *(u32 *)iv;
-+ return 4;
- }
-
-- if (ctx->mode != CONTEXT_CONTROL_CRYPTO_MODE_ECB) {
-- switch (ctx->alg) {
-- case SAFEXCEL_DES:
-- block_sz = DES_BLOCK_SIZE;
-- cdesc->control_data.options |= EIP197_OPTION_2_TOKEN_IV_CMD;
-- break;
-- case SAFEXCEL_3DES:
-- block_sz = DES3_EDE_BLOCK_SIZE;
-- cdesc->control_data.options |= EIP197_OPTION_2_TOKEN_IV_CMD;
-- break;
-- case SAFEXCEL_AES:
-- block_sz = AES_BLOCK_SIZE;
-- cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;
-- break;
-- }
-- memcpy(cdesc->control_data.token, iv, block_sz);
-- }
-+ cdesc->control_data.options |= ctx->ivmask;
-+ memcpy(cdesc->control_data.token, iv, ctx->blocksz);
-+ return ctx->blocksz / sizeof(u32);
- }
-
- static void safexcel_skcipher_token(struct safexcel_cipher_ctx *ctx, u8 *iv,
- struct safexcel_command_desc *cdesc,
-+ struct safexcel_token *atoken,
- u32 length)
- {
- struct safexcel_token *token;
-+ int ivlen;
-
-- safexcel_cipher_token(ctx, iv, cdesc);
--
-- /* skip over worst case IV of 4 dwords, no need to be exact */
-- token = (struct safexcel_token *)(cdesc->control_data.token + 4);
-+ ivlen = safexcel_skcipher_iv(ctx, iv, cdesc);
-+ if (ivlen == 4) {
-+ /* No space in cdesc, instruction moves to atoken */
-+ cdesc->additional_cdata_size = 1;
-+ token = atoken;
-+ } else {
-+ /* Everything fits in cdesc */
-+ token = (struct safexcel_token *)(cdesc->control_data.token + 2);
-+ /* Need to pad with NOP */
-+ eip197_noop_token(&token[1]);
-+ }
-+
-+ token->opcode = EIP197_TOKEN_OPCODE_DIRECTION;
-+ token->packet_length = length;
-+ token->stat = EIP197_TOKEN_STAT_LAST_PACKET |
-+ EIP197_TOKEN_STAT_LAST_HASH;
-+ token->instructions = EIP197_TOKEN_INS_LAST |
-+ EIP197_TOKEN_INS_TYPE_CRYPTO |
-+ EIP197_TOKEN_INS_TYPE_OUTPUT;
-+}
-
-- token[0].opcode = EIP197_TOKEN_OPCODE_DIRECTION;
-- token[0].packet_length = length;
-- token[0].stat = EIP197_TOKEN_STAT_LAST_PACKET |
-- EIP197_TOKEN_STAT_LAST_HASH;
-- token[0].instructions = EIP197_TOKEN_INS_LAST |
-- EIP197_TOKEN_INS_TYPE_CRYPTO |
-- EIP197_TOKEN_INS_TYPE_OUTPUT;
-+static void safexcel_aead_iv(struct safexcel_cipher_ctx *ctx, u8 *iv,
-+ struct safexcel_command_desc *cdesc)
-+{
-+ if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD ||
-+ ctx->aead & EIP197_AEAD_TYPE_IPSEC_ESP) { /* _ESP and _ESP_GMAC */
-+ /* 32 bit nonce */
-+ cdesc->control_data.token[0] = ctx->nonce;
-+ /* 64 bit IV part */
-+ memcpy(&cdesc->control_data.token[1], iv, 8);
-+ /* 32 bit counter, start at 0 or 1 (big endian!) */
-+ cdesc->control_data.token[3] =
-+ (__force u32)cpu_to_be32(ctx->ctrinit);
-+ return;
-+ }
-+ if (ctx->xcm == EIP197_XCM_MODE_GCM || ctx->alg == SAFEXCEL_CHACHA20) {
-+ /* 96 bit IV part */
-+ memcpy(&cdesc->control_data.token[0], iv, 12);
-+ /* 32 bit counter, start at 0 or 1 (big endian!) */
-+ cdesc->control_data.token[3] =
-+ (__force u32)cpu_to_be32(ctx->ctrinit);
-+ return;
-+ }
-+ /* CBC */
-+ memcpy(cdesc->control_data.token, iv, ctx->blocksz);
- }
-
- static void safexcel_aead_token(struct safexcel_cipher_ctx *ctx, u8 *iv,
- struct safexcel_command_desc *cdesc,
-+ struct safexcel_token *atoken,
- enum safexcel_cipher_direction direction,
- u32 cryptlen, u32 assoclen, u32 digestsize)
- {
-- struct safexcel_token *token;
-+ struct safexcel_token *aadref;
-+ int atoksize = 2; /* Start with minimum size */
-+ int assocadj = assoclen - ctx->aadskip, aadalign;
-
-- safexcel_cipher_token(ctx, iv, cdesc);
-+ /* Always 4 dwords of embedded IV for AEAD modes */
-+ cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;
-
-- if (direction == SAFEXCEL_ENCRYPT) {
-- /* align end of instruction sequence to end of token */
-- token = (struct safexcel_token *)(cdesc->control_data.token +
-- EIP197_MAX_TOKENS - 13);
--
-- token[12].opcode = EIP197_TOKEN_OPCODE_INSERT;
-- token[12].packet_length = digestsize;
-- token[12].stat = EIP197_TOKEN_STAT_LAST_HASH |
-- EIP197_TOKEN_STAT_LAST_PACKET;
-- token[12].instructions = EIP197_TOKEN_INS_TYPE_OUTPUT |
-- EIP197_TOKEN_INS_INSERT_HASH_DIGEST;
-- } else {
-+ if (direction == SAFEXCEL_DECRYPT)
- cryptlen -= digestsize;
-
-- /* align end of instruction sequence to end of token */
-- token = (struct safexcel_token *)(cdesc->control_data.token +
-- EIP197_MAX_TOKENS - 14);
--
-- token[12].opcode = EIP197_TOKEN_OPCODE_RETRIEVE;
-- token[12].packet_length = digestsize;
-- token[12].stat = EIP197_TOKEN_STAT_LAST_HASH |
-- EIP197_TOKEN_STAT_LAST_PACKET;
-- token[12].instructions = EIP197_TOKEN_INS_INSERT_HASH_DIGEST;
--
-- token[13].opcode = EIP197_TOKEN_OPCODE_VERIFY;
-- token[13].packet_length = digestsize |
-- EIP197_TOKEN_HASH_RESULT_VERIFY;
-- token[13].stat = EIP197_TOKEN_STAT_LAST_HASH |
-- EIP197_TOKEN_STAT_LAST_PACKET;
-- token[13].instructions = EIP197_TOKEN_INS_TYPE_OUTPUT;
-- }
--
-- token[6].opcode = EIP197_TOKEN_OPCODE_DIRECTION;
-- token[6].packet_length = assoclen;
--
-- if (likely(cryptlen)) {
-- token[6].instructions = EIP197_TOKEN_INS_TYPE_HASH;
--
-- token[10].opcode = EIP197_TOKEN_OPCODE_DIRECTION;
-- token[10].packet_length = cryptlen;
-- token[10].stat = EIP197_TOKEN_STAT_LAST_HASH;
-- token[10].instructions = EIP197_TOKEN_INS_LAST |
-- EIP197_TOKEN_INS_TYPE_CRYPTO |
-- EIP197_TOKEN_INS_TYPE_HASH |
-- EIP197_TOKEN_INS_TYPE_OUTPUT;
-- } else if (ctx->xcm != EIP197_XCM_MODE_CCM) {
-- token[6].stat = EIP197_TOKEN_STAT_LAST_HASH;
-- token[6].instructions = EIP197_TOKEN_INS_LAST |
-- EIP197_TOKEN_INS_TYPE_HASH;
-- }
--
-- if (!ctx->xcm)
-- return;
--
-- token[8].opcode = EIP197_TOKEN_OPCODE_INSERT_REMRES;
-- token[8].packet_length = 0;
-- token[8].instructions = AES_BLOCK_SIZE;
--
-- token[9].opcode = EIP197_TOKEN_OPCODE_INSERT;
-- token[9].packet_length = AES_BLOCK_SIZE;
-- token[9].instructions = EIP197_TOKEN_INS_TYPE_OUTPUT |
-- EIP197_TOKEN_INS_TYPE_CRYPTO;
--
-- if (ctx->xcm == EIP197_XCM_MODE_GCM) {
-- token[6].instructions = EIP197_TOKEN_INS_LAST |
-- EIP197_TOKEN_INS_TYPE_HASH;
-- } else {
-- u8 *cbcmaciv = (u8 *)&token[1];
-- u32 *aadlen = (u32 *)&token[5];
--
-+ if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM)) {
- /* Construct IV block B0 for the CBC-MAC */
-- token[0].opcode = EIP197_TOKEN_OPCODE_INSERT;
-- token[0].packet_length = AES_BLOCK_SIZE +
-- ((assoclen > 0) << 1);
-- token[0].instructions = EIP197_TOKEN_INS_ORIGIN_TOKEN |
-- EIP197_TOKEN_INS_TYPE_HASH;
-- /* Variable length IV part */
-- memcpy(cbcmaciv, iv, 15 - iv[0]);
-- /* fixup flags byte */
-- cbcmaciv[0] |= ((assoclen > 0) << 6) | ((digestsize - 2) << 2);
-- /* Clear upper bytes of variable message length to 0 */
-- memset(cbcmaciv + 15 - iv[0], 0, iv[0] - 1);
-- /* insert lower 2 bytes of message length */
-- cbcmaciv[14] = cryptlen >> 8;
-- cbcmaciv[15] = cryptlen & 255;
--
-- if (assoclen) {
-- *aadlen = cpu_to_le32(cpu_to_be16(assoclen));
-- assoclen += 2;
-+ u8 *final_iv = (u8 *)cdesc->control_data.token;
-+ u8 *cbcmaciv = (u8 *)&atoken[1];
-+ __le32 *aadlen = (__le32 *)&atoken[5];
-+
-+ if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) {
-+ /* Length + nonce */
-+ cdesc->control_data.token[0] = ctx->nonce;
-+ /* Fixup flags byte */
-+ *(__le32 *)cbcmaciv =
-+ cpu_to_le32(ctx->nonce |
-+ ((assocadj > 0) << 6) |
-+ ((digestsize - 2) << 2));
-+ /* 64 bit IV part */
-+ memcpy(&cdesc->control_data.token[1], iv, 8);
-+ memcpy(cbcmaciv + 4, iv, 8);
-+ /* Start counter at 0 */
-+ cdesc->control_data.token[3] = 0;
-+ /* Message length */
-+ *(__be32 *)(cbcmaciv + 12) = cpu_to_be32(cryptlen);
-+ } else {
-+ /* Variable length IV part */
-+ memcpy(final_iv, iv, 15 - iv[0]);
-+ memcpy(cbcmaciv, iv, 15 - iv[0]);
-+ /* Start variable length counter at 0 */
-+ memset(final_iv + 15 - iv[0], 0, iv[0] + 1);
-+ memset(cbcmaciv + 15 - iv[0], 0, iv[0] - 1);
-+ /* fixup flags byte */
-+ cbcmaciv[0] |= ((assocadj > 0) << 6) |
-+ ((digestsize - 2) << 2);
-+ /* insert lower 2 bytes of message length */
-+ cbcmaciv[14] = cryptlen >> 8;
-+ cbcmaciv[15] = cryptlen & 255;
-+ }
-+
-+ atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
-+ atoken->packet_length = AES_BLOCK_SIZE +
-+ ((assocadj > 0) << 1);
-+ atoken->stat = 0;
-+ atoken->instructions = EIP197_TOKEN_INS_ORIGIN_TOKEN |
-+ EIP197_TOKEN_INS_TYPE_HASH;
-+
-+ if (likely(assocadj)) {
-+ *aadlen = cpu_to_le32((assocadj >> 8) |
-+ (assocadj & 255) << 8);
-+ atoken += 6;
-+ atoksize += 7;
-+ } else {
-+ atoken += 5;
-+ atoksize += 6;
- }
-
-- token[6].instructions = EIP197_TOKEN_INS_TYPE_HASH;
--
-- /* Align AAD data towards hash engine */
-- token[7].opcode = EIP197_TOKEN_OPCODE_INSERT;
-- assoclen &= 15;
-- token[7].packet_length = assoclen ? 16 - assoclen : 0;
--
-+ /* Process AAD data */
-+ aadref = atoken;
-+ atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;
-+ atoken->packet_length = assocadj;
-+ atoken->stat = 0;
-+ atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH;
-+ atoken++;
-+
-+ /* For CCM only, align AAD data towards hash engine */
-+ atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
-+ aadalign = (assocadj + 2) & 15;
-+ atoken->packet_length = assocadj && aadalign ?
-+ 16 - aadalign :
-+ 0;
- if (likely(cryptlen)) {
-- token[7].instructions = EIP197_TOKEN_INS_TYPE_HASH;
--
-- /* Align crypto data towards hash engine */
-- token[10].stat = 0;
-+ atoken->stat = 0;
-+ atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH;
-+ } else {
-+ atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;
-+ atoken->instructions = EIP197_TOKEN_INS_LAST |
-+ EIP197_TOKEN_INS_TYPE_HASH;
-+ }
-+ } else {
-+ safexcel_aead_iv(ctx, iv, cdesc);
-
-- token[11].opcode = EIP197_TOKEN_OPCODE_INSERT;
-- cryptlen &= 15;
-- token[11].packet_length = cryptlen ? 16 - cryptlen : 0;
-- token[11].stat = EIP197_TOKEN_STAT_LAST_HASH;
-- token[11].instructions = EIP197_TOKEN_INS_TYPE_HASH;
-+ /* Process AAD data */
-+ aadref = atoken;
-+ atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;
-+ atoken->packet_length = assocadj;
-+ atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;
-+ atoken->instructions = EIP197_TOKEN_INS_LAST |
-+ EIP197_TOKEN_INS_TYPE_HASH;
-+ }
-+ atoken++;
-+
-+ if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) {
-+ /* For ESP mode (and not GMAC), skip over the IV */
-+ atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;
-+ atoken->packet_length = EIP197_AEAD_IPSEC_IV_SIZE;
-+ atoken->stat = 0;
-+ atoken->instructions = 0;
-+ atoken++;
-+ atoksize++;
-+ } else if (unlikely(ctx->alg == SAFEXCEL_CHACHA20 &&
-+ direction == SAFEXCEL_DECRYPT)) {
-+ /* Poly-chacha decryption needs a dummy NOP here ... */
-+ atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
-+ atoken->packet_length = 16; /* According to Op Manual */
-+ atoken->stat = 0;
-+ atoken->instructions = 0;
-+ atoken++;
-+ atoksize++;
-+ }
-+
-+ if (ctx->xcm) {
-+ /* For GCM and CCM, obtain enc(Y0) */
-+ atoken->opcode = EIP197_TOKEN_OPCODE_INSERT_REMRES;
-+ atoken->packet_length = 0;
-+ atoken->stat = 0;
-+ atoken->instructions = AES_BLOCK_SIZE;
-+ atoken++;
-+
-+ atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
-+ atoken->packet_length = AES_BLOCK_SIZE;
-+ atoken->stat = 0;
-+ atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT |
-+ EIP197_TOKEN_INS_TYPE_CRYPTO;
-+ atoken++;
-+ atoksize += 2;
-+ }
-+
-+ if (likely(cryptlen || ctx->alg == SAFEXCEL_CHACHA20)) {
-+ /* Fixup stat field for AAD direction instruction */
-+ aadref->stat = 0;
-+
-+ /* Process crypto data */
-+ atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;
-+ atoken->packet_length = cryptlen;
-+
-+ if (unlikely(ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) {
-+ /* Fixup instruction field for AAD dir instruction */
-+ aadref->instructions = EIP197_TOKEN_INS_TYPE_HASH;
-+
-+ /* Do not send to crypt engine in case of GMAC */
-+ atoken->instructions = EIP197_TOKEN_INS_LAST |
-+ EIP197_TOKEN_INS_TYPE_HASH |
-+ EIP197_TOKEN_INS_TYPE_OUTPUT;
-+ } else {
-+ atoken->instructions = EIP197_TOKEN_INS_LAST |
-+ EIP197_TOKEN_INS_TYPE_CRYPTO |
-+ EIP197_TOKEN_INS_TYPE_HASH |
-+ EIP197_TOKEN_INS_TYPE_OUTPUT;
-+ }
-+
-+ cryptlen &= 15;
-+ if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM && cryptlen)) {
-+ atoken->stat = 0;
-+ /* For CCM only, pad crypto data to the hash engine */
-+ atoken++;
-+ atoksize++;
-+ atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
-+ atoken->packet_length = 16 - cryptlen;
-+ atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;
-+ atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH;
- } else {
-- token[7].stat = EIP197_TOKEN_STAT_LAST_HASH;
-- token[7].instructions = EIP197_TOKEN_INS_LAST |
-- EIP197_TOKEN_INS_TYPE_HASH;
-+ atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;
- }
-+ atoken++;
-+ atoksize++;
- }
-+
-+ if (direction == SAFEXCEL_ENCRYPT) {
-+ /* Append ICV */
-+ atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
-+ atoken->packet_length = digestsize;
-+ atoken->stat = EIP197_TOKEN_STAT_LAST_HASH |
-+ EIP197_TOKEN_STAT_LAST_PACKET;
-+ atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT |
-+ EIP197_TOKEN_INS_INSERT_HASH_DIGEST;
-+ } else {
-+ /* Extract ICV */
-+ atoken->opcode = EIP197_TOKEN_OPCODE_RETRIEVE;
-+ atoken->packet_length = digestsize;
-+ atoken->stat = EIP197_TOKEN_STAT_LAST_HASH |
-+ EIP197_TOKEN_STAT_LAST_PACKET;
-+ atoken->instructions = EIP197_TOKEN_INS_INSERT_HASH_DIGEST;
-+ atoken++;
-+ atoksize++;
-+
-+ /* Verify ICV */
-+ atoken->opcode = EIP197_TOKEN_OPCODE_VERIFY;
-+ atoken->packet_length = digestsize |
-+ EIP197_TOKEN_HASH_RESULT_VERIFY;
-+ atoken->stat = EIP197_TOKEN_STAT_LAST_HASH |
-+ EIP197_TOKEN_STAT_LAST_PACKET;
-+ atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT;
-+ }
-+
-+ /* Fixup length of the token in the command descriptor */
-+ cdesc->additional_cdata_size = atoksize;
- }
-
- static int safexcel_skcipher_aes_setkey(struct crypto_skcipher *ctfm,
-@@ -277,14 +380,12 @@ static int safexcel_skcipher_aes_setkey(
- int ret, i;
-
- ret = aes_expandkey(&aes, key, len);
-- if (ret) {
-- crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
-+ if (ret)
- return ret;
-- }
-
- if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
- for (i = 0; i < len / sizeof(u32); i++) {
-- if (ctx->key[i] != cpu_to_le32(aes.key_enc[i])) {
-+ if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {
- ctx->base.needs_inv = true;
- break;
- }
-@@ -309,43 +410,57 @@ static int safexcel_aead_setkey(struct c
- struct safexcel_crypto_priv *priv = ctx->priv;
- struct crypto_authenc_keys keys;
- struct crypto_aes_ctx aes;
-- int err = -EINVAL;
-+ int err = -EINVAL, i;
-
-- if (crypto_authenc_extractkeys(&keys, key, len) != 0)
-+ if (unlikely(crypto_authenc_extractkeys(&keys, key, len)))
- goto badkey;
-
- if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) {
-- /* Minimum keysize is minimum AES key size + nonce size */
-- if (keys.enckeylen < (AES_MIN_KEY_SIZE +
-- CTR_RFC3686_NONCE_SIZE))
-+ /* Must have at least space for the nonce here */
-+ if (unlikely(keys.enckeylen < CTR_RFC3686_NONCE_SIZE))
- goto badkey;
- /* last 4 bytes of key are the nonce! */
- ctx->nonce = *(u32 *)(keys.enckey + keys.enckeylen -
- CTR_RFC3686_NONCE_SIZE);
- /* exclude the nonce here */
-- keys.enckeylen -= CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;
-+ keys.enckeylen -= CTR_RFC3686_NONCE_SIZE;
- }
-
- /* Encryption key */
- switch (ctx->alg) {
-+ case SAFEXCEL_DES:
-+ err = verify_aead_des_key(ctfm, keys.enckey, keys.enckeylen);
-+ if (unlikely(err))
-+ goto badkey;
-+ break;
- case SAFEXCEL_3DES:
- err = verify_aead_des3_key(ctfm, keys.enckey, keys.enckeylen);
- if (unlikely(err))
-- goto badkey_expflags;
-+ goto badkey;
- break;
- case SAFEXCEL_AES:
- err = aes_expandkey(&aes, keys.enckey, keys.enckeylen);
- if (unlikely(err))
- goto badkey;
- break;
-+ case SAFEXCEL_SM4:
-+ if (unlikely(keys.enckeylen != SM4_KEY_SIZE))
-+ goto badkey;
-+ break;
- default:
- dev_err(priv->dev, "aead: unsupported cipher algorithm\n");
- goto badkey;
- }
-
-- if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma &&
-- memcmp(ctx->key, keys.enckey, keys.enckeylen))
-- ctx->base.needs_inv = true;
-+ if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
-+ for (i = 0; i < keys.enckeylen / sizeof(u32); i++) {
-+ if (le32_to_cpu(ctx->key[i]) !=
-+ ((u32 *)keys.enckey)[i]) {
-+ ctx->base.needs_inv = true;
-+ break;
-+ }
-+ }
-+ }
-
- /* Auth key */
- switch (ctx->hash_alg) {
-@@ -374,21 +489,24 @@ static int safexcel_aead_setkey(struct c
- keys.authkeylen, &istate, &ostate))
- goto badkey;
- break;
-+ case CONTEXT_CONTROL_CRYPTO_ALG_SM3:
-+ if (safexcel_hmac_setkey("safexcel-sm3", keys.authkey,
-+ keys.authkeylen, &istate, &ostate))
-+ goto badkey;
-+ break;
- default:
- dev_err(priv->dev, "aead: unsupported hash algorithm\n");
- goto badkey;
- }
-
-- crypto_aead_set_flags(ctfm, crypto_aead_get_flags(ctfm) &
-- CRYPTO_TFM_RES_MASK);
--
- if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma &&
- (memcmp(ctx->ipad, istate.state, ctx->state_sz) ||
- memcmp(ctx->opad, ostate.state, ctx->state_sz)))
- ctx->base.needs_inv = true;
-
- /* Now copy the keys into the context */
-- memcpy(ctx->key, keys.enckey, keys.enckeylen);
-+ for (i = 0; i < keys.enckeylen / sizeof(u32); i++)
-+ ctx->key[i] = cpu_to_le32(((u32 *)keys.enckey)[i]);
- ctx->key_len = keys.enckeylen;
-
- memcpy(ctx->ipad, &istate.state, ctx->state_sz);
-@@ -398,8 +516,6 @@ static int safexcel_aead_setkey(struct c
- return 0;
-
- badkey:
-- crypto_aead_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
--badkey_expflags:
- memzero_explicit(&keys, sizeof(keys));
- return err;
- }
-@@ -423,6 +539,17 @@ static int safexcel_context_control(stru
- CONTEXT_CONTROL_DIGEST_XCM |
- ctx->hash_alg |
- CONTEXT_CONTROL_SIZE(ctrl_size);
-+ } else if (ctx->alg == SAFEXCEL_CHACHA20) {
-+ /* Chacha20-Poly1305 */
-+ cdesc->control_data.control0 =
-+ CONTEXT_CONTROL_KEY_EN |
-+ CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20 |
-+ (sreq->direction == SAFEXCEL_ENCRYPT ?
-+ CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT :
-+ CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN) |
-+ ctx->hash_alg |
-+ CONTEXT_CONTROL_SIZE(ctrl_size);
-+ return 0;
- } else {
- ctrl_size += ctx->state_sz / sizeof(u32) * 2;
- cdesc->control_data.control0 =
-@@ -431,17 +558,21 @@ static int safexcel_context_control(stru
- ctx->hash_alg |
- CONTEXT_CONTROL_SIZE(ctrl_size);
- }
-- if (sreq->direction == SAFEXCEL_ENCRYPT)
-- cdesc->control_data.control0 |=
-- (ctx->xcm == EIP197_XCM_MODE_CCM) ?
-- CONTEXT_CONTROL_TYPE_HASH_ENCRYPT_OUT :
-- CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT;
-
-+ if (sreq->direction == SAFEXCEL_ENCRYPT &&
-+ (ctx->xcm == EIP197_XCM_MODE_CCM ||
-+ ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC))
-+ cdesc->control_data.control0 |=
-+ CONTEXT_CONTROL_TYPE_HASH_ENCRYPT_OUT;
-+ else if (sreq->direction == SAFEXCEL_ENCRYPT)
-+ cdesc->control_data.control0 |=
-+ CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT;
-+ else if (ctx->xcm == EIP197_XCM_MODE_CCM)
-+ cdesc->control_data.control0 |=
-+ CONTEXT_CONTROL_TYPE_DECRYPT_HASH_IN;
- else
- cdesc->control_data.control0 |=
-- (ctx->xcm == EIP197_XCM_MODE_CCM) ?
-- CONTEXT_CONTROL_TYPE_DECRYPT_HASH_IN :
-- CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN;
-+ CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN;
- } else {
- if (sreq->direction == SAFEXCEL_ENCRYPT)
- cdesc->control_data.control0 =
-@@ -480,6 +611,12 @@ static int safexcel_context_control(stru
- ctx->key_len >> ctx->xts);
- return -EINVAL;
- }
-+ } else if (ctx->alg == SAFEXCEL_CHACHA20) {
-+ cdesc->control_data.control0 |=
-+ CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20;
-+ } else if (ctx->alg == SAFEXCEL_SM4) {
-+ cdesc->control_data.control0 |=
-+ CONTEXT_CONTROL_CRYPTO_ALG_SM4;
- }
-
- return 0;
-@@ -563,6 +700,7 @@ static int safexcel_send_req(struct cryp
- unsigned int totlen;
- unsigned int totlen_src = cryptlen + assoclen;
- unsigned int totlen_dst = totlen_src;
-+ struct safexcel_token *atoken;
- int n_cdesc = 0, n_rdesc = 0;
- int queued, i, ret = 0;
- bool first = true;
-@@ -637,56 +775,60 @@ static int safexcel_send_req(struct cryp
-
- memcpy(ctx->base.ctxr->data, ctx->key, ctx->key_len);
-
-- /* The EIP cannot deal with zero length input packets! */
-- if (totlen == 0)
-- totlen = 1;
-+ if (!totlen) {
-+ /*
-+ * The EIP97 cannot deal with zero length input packets!
-+ * So stuff a dummy command descriptor indicating a 1 byte
-+ * (dummy) input packet, using the context record as source.
-+ */
-+ first_cdesc = safexcel_add_cdesc(priv, ring,
-+ 1, 1, ctx->base.ctxr_dma,
-+ 1, 1, ctx->base.ctxr_dma,
-+ &atoken);
-+ if (IS_ERR(first_cdesc)) {
-+ /* No space left in the command descriptor ring */
-+ ret = PTR_ERR(first_cdesc);
-+ goto cdesc_rollback;
-+ }
-+ n_cdesc = 1;
-+ goto skip_cdesc;
-+ }
-
- /* command descriptors */
- for_each_sg(src, sg, sreq->nr_src, i) {
- int len = sg_dma_len(sg);
-
- /* Do not overflow the request */
-- if (queued - len < 0)
-+ if (queued < len)
- len = queued;
-
- cdesc = safexcel_add_cdesc(priv, ring, !n_cdesc,
- !(queued - len),
- sg_dma_address(sg), len, totlen,
-- ctx->base.ctxr_dma);
-+ ctx->base.ctxr_dma, &atoken);
- if (IS_ERR(cdesc)) {
- /* No space left in the command descriptor ring */
- ret = PTR_ERR(cdesc);
- goto cdesc_rollback;
- }
-- n_cdesc++;
-
-- if (n_cdesc == 1) {
-+ if (!n_cdesc)
- first_cdesc = cdesc;
-- }
-
-+ n_cdesc++;
- queued -= len;
- if (!queued)
- break;
- }
--
-- if (unlikely(!n_cdesc)) {
-- /*
-- * Special case: zero length input buffer.
-- * The engine always needs the 1st command descriptor, however!
-- */
-- first_cdesc = safexcel_add_cdesc(priv, ring, 1, 1, 0, 0, totlen,
-- ctx->base.ctxr_dma);
-- n_cdesc = 1;
-- }
--
-+skip_cdesc:
- /* Add context control words and token to first command descriptor */
- safexcel_context_control(ctx, base, sreq, first_cdesc);
- if (ctx->aead)
-- safexcel_aead_token(ctx, iv, first_cdesc,
-+ safexcel_aead_token(ctx, iv, first_cdesc, atoken,
- sreq->direction, cryptlen,
- assoclen, digestsize);
- else
-- safexcel_skcipher_token(ctx, iv, first_cdesc,
-+ safexcel_skcipher_token(ctx, iv, first_cdesc, atoken,
- cryptlen);
-
- /* result descriptors */
-@@ -1073,6 +1215,8 @@ static int safexcel_skcipher_cra_init(st
-
- ctx->base.send = safexcel_skcipher_send;
- ctx->base.handle_result = safexcel_skcipher_handle_result;
-+ ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD;
-+ ctx->ctrinit = 1;
- return 0;
- }
-
-@@ -1137,6 +1281,8 @@ static int safexcel_skcipher_aes_ecb_cra
- safexcel_skcipher_cra_init(tfm);
- ctx->alg = SAFEXCEL_AES;
- ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;
-+ ctx->blocksz = 0;
-+ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
- return 0;
- }
-
-@@ -1171,6 +1317,7 @@ static int safexcel_skcipher_aes_cbc_cra
-
- safexcel_skcipher_cra_init(tfm);
- ctx->alg = SAFEXCEL_AES;
-+ ctx->blocksz = AES_BLOCK_SIZE;
- ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;
- return 0;
- }
-@@ -1207,6 +1354,7 @@ static int safexcel_skcipher_aes_cfb_cra
-
- safexcel_skcipher_cra_init(tfm);
- ctx->alg = SAFEXCEL_AES;
-+ ctx->blocksz = AES_BLOCK_SIZE;
- ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB;
- return 0;
- }
-@@ -1243,6 +1391,7 @@ static int safexcel_skcipher_aes_ofb_cra
-
- safexcel_skcipher_cra_init(tfm);
- ctx->alg = SAFEXCEL_AES;
-+ ctx->blocksz = AES_BLOCK_SIZE;
- ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB;
- return 0;
- }
-@@ -1288,14 +1437,12 @@ static int safexcel_skcipher_aesctr_setk
- /* exclude the nonce here */
- keylen = len - CTR_RFC3686_NONCE_SIZE;
- ret = aes_expandkey(&aes, key, keylen);
-- if (ret) {
-- crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
-+ if (ret)
- return ret;
-- }
-
- if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
- for (i = 0; i < keylen / sizeof(u32); i++) {
-- if (ctx->key[i] != cpu_to_le32(aes.key_enc[i])) {
-+ if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {
- ctx->base.needs_inv = true;
- break;
- }
-@@ -1317,6 +1464,7 @@ static int safexcel_skcipher_aes_ctr_cra
-
- safexcel_skcipher_cra_init(tfm);
- ctx->alg = SAFEXCEL_AES;
-+ ctx->blocksz = AES_BLOCK_SIZE;
- ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;
- return 0;
- }
-@@ -1352,6 +1500,7 @@ static int safexcel_des_setkey(struct cr
- unsigned int len)
- {
- struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm);
-+ struct safexcel_crypto_priv *priv = ctx->priv;
- int ret;
-
- ret = verify_skcipher_des_key(ctfm, key);
-@@ -1359,7 +1508,7 @@ static int safexcel_des_setkey(struct cr
- return ret;
-
- /* if context exits and key changed, need to invalidate it */
-- if (ctx->base.ctxr_dma)
-+ if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)
- if (memcmp(ctx->key, key, len))
- ctx->base.needs_inv = true;
-
-@@ -1375,6 +1524,8 @@ static int safexcel_skcipher_des_cbc_cra
-
- safexcel_skcipher_cra_init(tfm);
- ctx->alg = SAFEXCEL_DES;
-+ ctx->blocksz = DES_BLOCK_SIZE;
-+ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
- ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;
- return 0;
- }
-@@ -1412,6 +1563,8 @@ static int safexcel_skcipher_des_ecb_cra
- safexcel_skcipher_cra_init(tfm);
- ctx->alg = SAFEXCEL_DES;
- ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;
-+ ctx->blocksz = 0;
-+ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
- return 0;
- }
-
-@@ -1444,6 +1597,7 @@ static int safexcel_des3_ede_setkey(stru
- const u8 *key, unsigned int len)
- {
- struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm);
-+ struct safexcel_crypto_priv *priv = ctx->priv;
- int err;
-
- err = verify_skcipher_des3_key(ctfm, key);
-@@ -1451,13 +1605,11 @@ static int safexcel_des3_ede_setkey(stru
- return err;
-
- /* if context exits and key changed, need to invalidate it */
-- if (ctx->base.ctxr_dma) {
-+ if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)
- if (memcmp(ctx->key, key, len))
- ctx->base.needs_inv = true;
-- }
-
- memcpy(ctx->key, key, len);
--
- ctx->key_len = len;
-
- return 0;
-@@ -1469,6 +1621,8 @@ static int safexcel_skcipher_des3_cbc_cr
-
- safexcel_skcipher_cra_init(tfm);
- ctx->alg = SAFEXCEL_3DES;
-+ ctx->blocksz = DES3_EDE_BLOCK_SIZE;
-+ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
- ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;
- return 0;
- }
-@@ -1506,6 +1660,8 @@ static int safexcel_skcipher_des3_ecb_cr
- safexcel_skcipher_cra_init(tfm);
- ctx->alg = SAFEXCEL_3DES;
- ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;
-+ ctx->blocksz = 0;
-+ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
- return 0;
- }
-
-@@ -1561,6 +1717,9 @@ static int safexcel_aead_cra_init(struct
- ctx->priv = tmpl->priv;
-
- ctx->alg = SAFEXCEL_AES; /* default */
-+ ctx->blocksz = AES_BLOCK_SIZE;
-+ ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD;
-+ ctx->ctrinit = 1;
- ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; /* default */
- ctx->aead = true;
- ctx->base.send = safexcel_aead_send;
-@@ -1749,6 +1908,8 @@ static int safexcel_aead_sha1_des3_cra_i
-
- safexcel_aead_sha1_cra_init(tfm);
- ctx->alg = SAFEXCEL_3DES; /* override default */
-+ ctx->blocksz = DES3_EDE_BLOCK_SIZE;
-+ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
- return 0;
- }
-
-@@ -1777,6 +1938,330 @@ struct safexcel_alg_template safexcel_al
- },
- };
-
-+static int safexcel_aead_sha256_des3_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_aead_sha256_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_3DES; /* override default */
-+ ctx->blocksz = DES3_EDE_BLOCK_SIZE;
-+ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des3_ede = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,
-+ .alg.aead = {
-+ .setkey = safexcel_aead_setkey,
-+ .encrypt = safexcel_aead_encrypt,
-+ .decrypt = safexcel_aead_decrypt,
-+ .ivsize = DES3_EDE_BLOCK_SIZE,
-+ .maxauthsize = SHA256_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha256),cbc(des3_ede))",
-+ .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des3_ede",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_aead_sha256_des3_cra_init,
-+ .cra_exit = safexcel_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_aead_sha224_des3_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_aead_sha224_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_3DES; /* override default */
-+ ctx->blocksz = DES3_EDE_BLOCK_SIZE;
-+ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des3_ede = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,
-+ .alg.aead = {
-+ .setkey = safexcel_aead_setkey,
-+ .encrypt = safexcel_aead_encrypt,
-+ .decrypt = safexcel_aead_decrypt,
-+ .ivsize = DES3_EDE_BLOCK_SIZE,
-+ .maxauthsize = SHA224_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha224),cbc(des3_ede))",
-+ .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des3_ede",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_aead_sha224_des3_cra_init,
-+ .cra_exit = safexcel_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_aead_sha512_des3_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_aead_sha512_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_3DES; /* override default */
-+ ctx->blocksz = DES3_EDE_BLOCK_SIZE;
-+ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des3_ede = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,
-+ .alg.aead = {
-+ .setkey = safexcel_aead_setkey,
-+ .encrypt = safexcel_aead_encrypt,
-+ .decrypt = safexcel_aead_decrypt,
-+ .ivsize = DES3_EDE_BLOCK_SIZE,
-+ .maxauthsize = SHA512_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha512),cbc(des3_ede))",
-+ .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des3_ede",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_aead_sha512_des3_cra_init,
-+ .cra_exit = safexcel_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_aead_sha384_des3_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_aead_sha384_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_3DES; /* override default */
-+ ctx->blocksz = DES3_EDE_BLOCK_SIZE;
-+ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des3_ede = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,
-+ .alg.aead = {
-+ .setkey = safexcel_aead_setkey,
-+ .encrypt = safexcel_aead_encrypt,
-+ .decrypt = safexcel_aead_decrypt,
-+ .ivsize = DES3_EDE_BLOCK_SIZE,
-+ .maxauthsize = SHA384_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha384),cbc(des3_ede))",
-+ .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des3_ede",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_aead_sha384_des3_cra_init,
-+ .cra_exit = safexcel_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_aead_sha1_des_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_aead_sha1_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_DES; /* override default */
-+ ctx->blocksz = DES_BLOCK_SIZE;
-+ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1,
-+ .alg.aead = {
-+ .setkey = safexcel_aead_setkey,
-+ .encrypt = safexcel_aead_encrypt,
-+ .decrypt = safexcel_aead_decrypt,
-+ .ivsize = DES_BLOCK_SIZE,
-+ .maxauthsize = SHA1_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha1),cbc(des))",
-+ .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_aead_sha1_des_cra_init,
-+ .cra_exit = safexcel_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_aead_sha256_des_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_aead_sha256_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_DES; /* override default */
-+ ctx->blocksz = DES_BLOCK_SIZE;
-+ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,
-+ .alg.aead = {
-+ .setkey = safexcel_aead_setkey,
-+ .encrypt = safexcel_aead_encrypt,
-+ .decrypt = safexcel_aead_decrypt,
-+ .ivsize = DES_BLOCK_SIZE,
-+ .maxauthsize = SHA256_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha256),cbc(des))",
-+ .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_aead_sha256_des_cra_init,
-+ .cra_exit = safexcel_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_aead_sha224_des_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_aead_sha224_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_DES; /* override default */
-+ ctx->blocksz = DES_BLOCK_SIZE;
-+ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,
-+ .alg.aead = {
-+ .setkey = safexcel_aead_setkey,
-+ .encrypt = safexcel_aead_encrypt,
-+ .decrypt = safexcel_aead_decrypt,
-+ .ivsize = DES_BLOCK_SIZE,
-+ .maxauthsize = SHA224_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha224),cbc(des))",
-+ .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_aead_sha224_des_cra_init,
-+ .cra_exit = safexcel_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_aead_sha512_des_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_aead_sha512_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_DES; /* override default */
-+ ctx->blocksz = DES_BLOCK_SIZE;
-+ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,
-+ .alg.aead = {
-+ .setkey = safexcel_aead_setkey,
-+ .encrypt = safexcel_aead_encrypt,
-+ .decrypt = safexcel_aead_decrypt,
-+ .ivsize = DES_BLOCK_SIZE,
-+ .maxauthsize = SHA512_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha512),cbc(des))",
-+ .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_aead_sha512_des_cra_init,
-+ .cra_exit = safexcel_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_aead_sha384_des_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_aead_sha384_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_DES; /* override default */
-+ ctx->blocksz = DES_BLOCK_SIZE;
-+ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,
-+ .alg.aead = {
-+ .setkey = safexcel_aead_setkey,
-+ .encrypt = safexcel_aead_encrypt,
-+ .decrypt = safexcel_aead_decrypt,
-+ .ivsize = DES_BLOCK_SIZE,
-+ .maxauthsize = SHA384_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha384),cbc(des))",
-+ .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_aead_sha384_des_cra_init,
-+ .cra_exit = safexcel_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
- static int safexcel_aead_sha1_ctr_cra_init(struct crypto_tfm *tfm)
- {
- struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-@@ -1965,14 +2450,12 @@ static int safexcel_skcipher_aesxts_setk
- /* Only half of the key data is cipher key */
- keylen = (len >> 1);
- ret = aes_expandkey(&aes, key, keylen);
-- if (ret) {
-- crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
-+ if (ret)
- return ret;
-- }
-
- if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
- for (i = 0; i < keylen / sizeof(u32); i++) {
-- if (ctx->key[i] != cpu_to_le32(aes.key_enc[i])) {
-+ if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {
- ctx->base.needs_inv = true;
- break;
- }
-@@ -1984,15 +2467,13 @@ static int safexcel_skcipher_aesxts_setk
-
- /* The other half is the tweak key */
- ret = aes_expandkey(&aes, (u8 *)(key + keylen), keylen);
-- if (ret) {
-- crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
-+ if (ret)
- return ret;
-- }
-
- if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
- for (i = 0; i < keylen / sizeof(u32); i++) {
-- if (ctx->key[i + keylen / sizeof(u32)] !=
-- cpu_to_le32(aes.key_enc[i])) {
-+ if (le32_to_cpu(ctx->key[i + keylen / sizeof(u32)]) !=
-+ aes.key_enc[i]) {
- ctx->base.needs_inv = true;
- break;
- }
-@@ -2015,6 +2496,7 @@ static int safexcel_skcipher_aes_xts_cra
-
- safexcel_skcipher_cra_init(tfm);
- ctx->alg = SAFEXCEL_AES;
-+ ctx->blocksz = AES_BLOCK_SIZE;
- ctx->xts = 1;
- ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XTS;
- return 0;
-@@ -2075,14 +2557,13 @@ static int safexcel_aead_gcm_setkey(stru
-
- ret = aes_expandkey(&aes, key, len);
- if (ret) {
-- crypto_aead_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
- memzero_explicit(&aes, sizeof(aes));
- return ret;
- }
-
- if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
- for (i = 0; i < len / sizeof(u32); i++) {
-- if (ctx->key[i] != cpu_to_le32(aes.key_enc[i])) {
-+ if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {
- ctx->base.needs_inv = true;
- break;
- }
-@@ -2099,8 +2580,6 @@ static int safexcel_aead_gcm_setkey(stru
- crypto_cipher_set_flags(ctx->hkaes, crypto_aead_get_flags(ctfm) &
- CRYPTO_TFM_REQ_MASK);
- ret = crypto_cipher_setkey(ctx->hkaes, key, len);
-- crypto_aead_set_flags(ctfm, crypto_cipher_get_flags(ctx->hkaes) &
-- CRYPTO_TFM_RES_MASK);
- if (ret)
- return ret;
-
-@@ -2109,7 +2588,7 @@ static int safexcel_aead_gcm_setkey(stru
-
- if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
- for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) {
-- if (ctx->ipad[i] != cpu_to_be32(hashkey[i])) {
-+ if (be32_to_cpu(ctx->ipad[i]) != hashkey[i]) {
- ctx->base.needs_inv = true;
- break;
- }
-@@ -2135,10 +2614,7 @@ static int safexcel_aead_gcm_cra_init(st
- ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */
-
- ctx->hkaes = crypto_alloc_cipher("aes", 0, 0);
-- if (IS_ERR(ctx->hkaes))
-- return PTR_ERR(ctx->hkaes);
--
-- return 0;
-+ return PTR_ERR_OR_ZERO(ctx->hkaes);
- }
-
- static void safexcel_aead_gcm_cra_exit(struct crypto_tfm *tfm)
-@@ -2192,14 +2668,13 @@ static int safexcel_aead_ccm_setkey(stru
-
- ret = aes_expandkey(&aes, key, len);
- if (ret) {
-- crypto_aead_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
- memzero_explicit(&aes, sizeof(aes));
- return ret;
- }
-
- if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
- for (i = 0; i < len / sizeof(u32); i++) {
-- if (ctx->key[i] != cpu_to_le32(aes.key_enc[i])) {
-+ if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {
- ctx->base.needs_inv = true;
- break;
- }
-@@ -2235,6 +2710,7 @@ static int safexcel_aead_ccm_cra_init(st
- ctx->state_sz = 3 * AES_BLOCK_SIZE;
- ctx->xcm = EIP197_XCM_MODE_CCM;
- ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */
-+ ctx->ctrinit = 0;
- return 0;
- }
-
-@@ -2301,5 +2777,949 @@ struct safexcel_alg_template safexcel_al
- .cra_exit = safexcel_aead_cra_exit,
- .cra_module = THIS_MODULE,
- },
-+ },
-+};
-+
-+static void safexcel_chacha20_setkey(struct safexcel_cipher_ctx *ctx,
-+ const u8 *key)
-+{
-+ struct safexcel_crypto_priv *priv = ctx->priv;
-+
-+ if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)
-+ if (memcmp(ctx->key, key, CHACHA_KEY_SIZE))
-+ ctx->base.needs_inv = true;
-+
-+ memcpy(ctx->key, key, CHACHA_KEY_SIZE);
-+ ctx->key_len = CHACHA_KEY_SIZE;
-+}
-+
-+static int safexcel_skcipher_chacha20_setkey(struct crypto_skcipher *ctfm,
-+ const u8 *key, unsigned int len)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm);
-+
-+ if (len != CHACHA_KEY_SIZE)
-+ return -EINVAL;
-+
-+ safexcel_chacha20_setkey(ctx, key);
-+
-+ return 0;
-+}
-+
-+static int safexcel_skcipher_chacha20_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_skcipher_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_CHACHA20;
-+ ctx->ctrinit = 0;
-+ ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_chacha20 = {
-+ .type = SAFEXCEL_ALG_TYPE_SKCIPHER,
-+ .algo_mask = SAFEXCEL_ALG_CHACHA20,
-+ .alg.skcipher = {
-+ .setkey = safexcel_skcipher_chacha20_setkey,
-+ .encrypt = safexcel_encrypt,
-+ .decrypt = safexcel_decrypt,
-+ .min_keysize = CHACHA_KEY_SIZE,
-+ .max_keysize = CHACHA_KEY_SIZE,
-+ .ivsize = CHACHA_IV_SIZE,
-+ .base = {
-+ .cra_name = "chacha20",
-+ .cra_driver_name = "safexcel-chacha20",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_skcipher_chacha20_cra_init,
-+ .cra_exit = safexcel_skcipher_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_aead_chachapoly_setkey(struct crypto_aead *ctfm,
-+ const u8 *key, unsigned int len)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_aead_ctx(ctfm);
-+
-+ if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP &&
-+ len > EIP197_AEAD_IPSEC_NONCE_SIZE) {
-+ /* ESP variant has nonce appended to key */
-+ len -= EIP197_AEAD_IPSEC_NONCE_SIZE;
-+ ctx->nonce = *(u32 *)(key + len);
-+ }
-+ if (len != CHACHA_KEY_SIZE)
-+ return -EINVAL;
-+
-+ safexcel_chacha20_setkey(ctx, key);
-+
-+ return 0;
-+}
-+
-+static int safexcel_aead_chachapoly_setauthsize(struct crypto_aead *tfm,
-+ unsigned int authsize)
-+{
-+ if (authsize != POLY1305_DIGEST_SIZE)
-+ return -EINVAL;
-+ return 0;
-+}
-+
-+static int safexcel_aead_chachapoly_crypt(struct aead_request *req,
-+ enum safexcel_cipher_direction dir)
-+{
-+ struct safexcel_cipher_req *creq = aead_request_ctx(req);
-+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
-+ struct crypto_tfm *tfm = crypto_aead_tfm(aead);
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+ struct aead_request *subreq = aead_request_ctx(req);
-+ u32 key[CHACHA_KEY_SIZE / sizeof(u32) + 1];
-+ int ret = 0;
-+
-+ /*
-+ * Instead of wasting time detecting umpteen silly corner cases,
-+ * just dump all "small" requests to the fallback implementation.
-+ * HW would not be faster on such small requests anyway.
-+ */
-+ if (likely((ctx->aead != EIP197_AEAD_TYPE_IPSEC_ESP ||
-+ req->assoclen >= EIP197_AEAD_IPSEC_IV_SIZE) &&
-+ req->cryptlen > POLY1305_DIGEST_SIZE)) {
-+ return safexcel_queue_req(&req->base, creq, dir);
-+ }
-+
-+ /* HW cannot do full (AAD+payload) zero length, use fallback */
-+ memcpy(key, ctx->key, CHACHA_KEY_SIZE);
-+ if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) {
-+ /* ESP variant has nonce appended to the key */
-+ key[CHACHA_KEY_SIZE / sizeof(u32)] = ctx->nonce;
-+ ret = crypto_aead_setkey(ctx->fback, (u8 *)key,
-+ CHACHA_KEY_SIZE +
-+ EIP197_AEAD_IPSEC_NONCE_SIZE);
-+ } else {
-+ ret = crypto_aead_setkey(ctx->fback, (u8 *)key,
-+ CHACHA_KEY_SIZE);
-+ }
-+ if (ret) {
-+ crypto_aead_clear_flags(aead, CRYPTO_TFM_REQ_MASK);
-+ crypto_aead_set_flags(aead, crypto_aead_get_flags(ctx->fback) &
-+ CRYPTO_TFM_REQ_MASK);
-+ return ret;
-+ }
-+
-+ aead_request_set_tfm(subreq, ctx->fback);
-+ aead_request_set_callback(subreq, req->base.flags, req->base.complete,
-+ req->base.data);
-+ aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,
-+ req->iv);
-+ aead_request_set_ad(subreq, req->assoclen);
-+
-+ return (dir == SAFEXCEL_ENCRYPT) ?
-+ crypto_aead_encrypt(subreq) :
-+ crypto_aead_decrypt(subreq);
-+}
-+
-+static int safexcel_aead_chachapoly_encrypt(struct aead_request *req)
-+{
-+ return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_ENCRYPT);
-+}
-+
-+static int safexcel_aead_chachapoly_decrypt(struct aead_request *req)
-+{
-+ return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_DECRYPT);
-+}
-+
-+static int safexcel_aead_fallback_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct crypto_aead *aead = __crypto_aead_cast(tfm);
-+ struct aead_alg *alg = crypto_aead_alg(aead);
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_aead_cra_init(tfm);
-+
-+ /* Allocate fallback implementation */
-+ ctx->fback = crypto_alloc_aead(alg->base.cra_name, 0,
-+ CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_NEED_FALLBACK);
-+ if (IS_ERR(ctx->fback))
-+ return PTR_ERR(ctx->fback);
-+
-+ crypto_aead_set_reqsize(aead, max(sizeof(struct safexcel_cipher_req),
-+ sizeof(struct aead_request) +
-+ crypto_aead_reqsize(ctx->fback)));
-+
-+ return 0;
-+}
-+
-+static int safexcel_aead_chachapoly_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_aead_fallback_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_CHACHA20;
-+ ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32 |
-+ CONTEXT_CONTROL_CHACHA20_MODE_CALC_OTK;
-+ ctx->ctrinit = 0;
-+ ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_POLY1305;
-+ ctx->state_sz = 0; /* Precomputed by HW */
-+ return 0;
-+}
-+
-+static void safexcel_aead_fallback_cra_exit(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ crypto_free_aead(ctx->fback);
-+ safexcel_aead_cra_exit(tfm);
-+}
-+
-+struct safexcel_alg_template safexcel_alg_chachapoly = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305,
-+ .alg.aead = {
-+ .setkey = safexcel_aead_chachapoly_setkey,
-+ .setauthsize = safexcel_aead_chachapoly_setauthsize,
-+ .encrypt = safexcel_aead_chachapoly_encrypt,
-+ .decrypt = safexcel_aead_chachapoly_decrypt,
-+ .ivsize = CHACHAPOLY_IV_SIZE,
-+ .maxauthsize = POLY1305_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "rfc7539(chacha20,poly1305)",
-+ .cra_driver_name = "safexcel-chacha20-poly1305",
-+ /* +1 to put it above HW chacha + SW poly */
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY + 1,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY |
-+ CRYPTO_ALG_NEED_FALLBACK,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_aead_chachapoly_cra_init,
-+ .cra_exit = safexcel_aead_fallback_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_aead_chachapolyesp_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+ int ret;
-+
-+ ret = safexcel_aead_chachapoly_cra_init(tfm);
-+ ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP;
-+ ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE;
-+ return ret;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_chachapoly_esp = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305,
-+ .alg.aead = {
-+ .setkey = safexcel_aead_chachapoly_setkey,
-+ .setauthsize = safexcel_aead_chachapoly_setauthsize,
-+ .encrypt = safexcel_aead_chachapoly_encrypt,
-+ .decrypt = safexcel_aead_chachapoly_decrypt,
-+ .ivsize = CHACHAPOLY_IV_SIZE - EIP197_AEAD_IPSEC_NONCE_SIZE,
-+ .maxauthsize = POLY1305_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "rfc7539esp(chacha20,poly1305)",
-+ .cra_driver_name = "safexcel-chacha20-poly1305-esp",
-+ /* +1 to put it above HW chacha + SW poly */
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY + 1,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY |
-+ CRYPTO_ALG_NEED_FALLBACK,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_aead_chachapolyesp_cra_init,
-+ .cra_exit = safexcel_aead_fallback_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_skcipher_sm4_setkey(struct crypto_skcipher *ctfm,
-+ const u8 *key, unsigned int len)
-+{
-+ struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+ struct safexcel_crypto_priv *priv = ctx->priv;
-+
-+ if (len != SM4_KEY_SIZE)
-+ return -EINVAL;
-+
-+ if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)
-+ if (memcmp(ctx->key, key, SM4_KEY_SIZE))
-+ ctx->base.needs_inv = true;
-+
-+ memcpy(ctx->key, key, SM4_KEY_SIZE);
-+ ctx->key_len = SM4_KEY_SIZE;
-+
-+ return 0;
-+}
-+
-+static int safexcel_sm4_blk_encrypt(struct skcipher_request *req)
-+{
-+ /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
-+ if (req->cryptlen & (SM4_BLOCK_SIZE - 1))
-+ return -EINVAL;
-+ else
-+ return safexcel_queue_req(&req->base, skcipher_request_ctx(req),
-+ SAFEXCEL_ENCRYPT);
-+}
-+
-+static int safexcel_sm4_blk_decrypt(struct skcipher_request *req)
-+{
-+ /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
-+ if (req->cryptlen & (SM4_BLOCK_SIZE - 1))
-+ return -EINVAL;
-+ else
-+ return safexcel_queue_req(&req->base, skcipher_request_ctx(req),
-+ SAFEXCEL_DECRYPT);
-+}
-+
-+static int safexcel_skcipher_sm4_ecb_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_skcipher_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_SM4;
-+ ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;
-+ ctx->blocksz = 0;
-+ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_ecb_sm4 = {
-+ .type = SAFEXCEL_ALG_TYPE_SKCIPHER,
-+ .algo_mask = SAFEXCEL_ALG_SM4,
-+ .alg.skcipher = {
-+ .setkey = safexcel_skcipher_sm4_setkey,
-+ .encrypt = safexcel_sm4_blk_encrypt,
-+ .decrypt = safexcel_sm4_blk_decrypt,
-+ .min_keysize = SM4_KEY_SIZE,
-+ .max_keysize = SM4_KEY_SIZE,
-+ .base = {
-+ .cra_name = "ecb(sm4)",
-+ .cra_driver_name = "safexcel-ecb-sm4",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = SM4_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_skcipher_sm4_ecb_cra_init,
-+ .cra_exit = safexcel_skcipher_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_skcipher_sm4_cbc_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_skcipher_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_SM4;
-+ ctx->blocksz = SM4_BLOCK_SIZE;
-+ ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_cbc_sm4 = {
-+ .type = SAFEXCEL_ALG_TYPE_SKCIPHER,
-+ .algo_mask = SAFEXCEL_ALG_SM4,
-+ .alg.skcipher = {
-+ .setkey = safexcel_skcipher_sm4_setkey,
-+ .encrypt = safexcel_sm4_blk_encrypt,
-+ .decrypt = safexcel_sm4_blk_decrypt,
-+ .min_keysize = SM4_KEY_SIZE,
-+ .max_keysize = SM4_KEY_SIZE,
-+ .ivsize = SM4_BLOCK_SIZE,
-+ .base = {
-+ .cra_name = "cbc(sm4)",
-+ .cra_driver_name = "safexcel-cbc-sm4",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = SM4_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_skcipher_sm4_cbc_cra_init,
-+ .cra_exit = safexcel_skcipher_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_skcipher_sm4_ofb_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_skcipher_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_SM4;
-+ ctx->blocksz = SM4_BLOCK_SIZE;
-+ ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_ofb_sm4 = {
-+ .type = SAFEXCEL_ALG_TYPE_SKCIPHER,
-+ .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB,
-+ .alg.skcipher = {
-+ .setkey = safexcel_skcipher_sm4_setkey,
-+ .encrypt = safexcel_encrypt,
-+ .decrypt = safexcel_decrypt,
-+ .min_keysize = SM4_KEY_SIZE,
-+ .max_keysize = SM4_KEY_SIZE,
-+ .ivsize = SM4_BLOCK_SIZE,
-+ .base = {
-+ .cra_name = "ofb(sm4)",
-+ .cra_driver_name = "safexcel-ofb-sm4",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_skcipher_sm4_ofb_cra_init,
-+ .cra_exit = safexcel_skcipher_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_skcipher_sm4_cfb_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_skcipher_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_SM4;
-+ ctx->blocksz = SM4_BLOCK_SIZE;
-+ ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_cfb_sm4 = {
-+ .type = SAFEXCEL_ALG_TYPE_SKCIPHER,
-+ .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB,
-+ .alg.skcipher = {
-+ .setkey = safexcel_skcipher_sm4_setkey,
-+ .encrypt = safexcel_encrypt,
-+ .decrypt = safexcel_decrypt,
-+ .min_keysize = SM4_KEY_SIZE,
-+ .max_keysize = SM4_KEY_SIZE,
-+ .ivsize = SM4_BLOCK_SIZE,
-+ .base = {
-+ .cra_name = "cfb(sm4)",
-+ .cra_driver_name = "safexcel-cfb-sm4",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_skcipher_sm4_cfb_cra_init,
-+ .cra_exit = safexcel_skcipher_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_skcipher_sm4ctr_setkey(struct crypto_skcipher *ctfm,
-+ const u8 *key, unsigned int len)
-+{
-+ struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ /* last 4 bytes of key are the nonce! */
-+ ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE);
-+ /* exclude the nonce here */
-+ len -= CTR_RFC3686_NONCE_SIZE;
-+
-+ return safexcel_skcipher_sm4_setkey(ctfm, key, len);
-+}
-+
-+static int safexcel_skcipher_sm4_ctr_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_skcipher_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_SM4;
-+ ctx->blocksz = SM4_BLOCK_SIZE;
-+ ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_ctr_sm4 = {
-+ .type = SAFEXCEL_ALG_TYPE_SKCIPHER,
-+ .algo_mask = SAFEXCEL_ALG_SM4,
-+ .alg.skcipher = {
-+ .setkey = safexcel_skcipher_sm4ctr_setkey,
-+ .encrypt = safexcel_encrypt,
-+ .decrypt = safexcel_decrypt,
-+ /* Add nonce size */
-+ .min_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
-+ .max_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
-+ .ivsize = CTR_RFC3686_IV_SIZE,
-+ .base = {
-+ .cra_name = "rfc3686(ctr(sm4))",
-+ .cra_driver_name = "safexcel-ctr-sm4",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_skcipher_sm4_ctr_cra_init,
-+ .cra_exit = safexcel_skcipher_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_aead_sm4_blk_encrypt(struct aead_request *req)
-+{
-+ /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
-+ if (req->cryptlen & (SM4_BLOCK_SIZE - 1))
-+ return -EINVAL;
-+
-+ return safexcel_queue_req(&req->base, aead_request_ctx(req),
-+ SAFEXCEL_ENCRYPT);
-+}
-+
-+static int safexcel_aead_sm4_blk_decrypt(struct aead_request *req)
-+{
-+ struct crypto_aead *tfm = crypto_aead_reqtfm(req);
-+
-+ /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
-+ if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1))
-+ return -EINVAL;
-+
-+ return safexcel_queue_req(&req->base, aead_request_ctx(req),
-+ SAFEXCEL_DECRYPT);
-+}
-+
-+static int safexcel_aead_sm4cbc_sha1_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_aead_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_SM4;
-+ ctx->blocksz = SM4_BLOCK_SIZE;
-+ ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1;
-+ ctx->state_sz = SHA1_DIGEST_SIZE;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_sm4 = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1,
-+ .alg.aead = {
-+ .setkey = safexcel_aead_setkey,
-+ .encrypt = safexcel_aead_sm4_blk_encrypt,
-+ .decrypt = safexcel_aead_sm4_blk_decrypt,
-+ .ivsize = SM4_BLOCK_SIZE,
-+ .maxauthsize = SHA1_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha1),cbc(sm4))",
-+ .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-sm4",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = SM4_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_aead_sm4cbc_sha1_cra_init,
-+ .cra_exit = safexcel_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_aead_fallback_setkey(struct crypto_aead *ctfm,
-+ const u8 *key, unsigned int len)
-+{
-+ struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ /* Keep fallback cipher synchronized */
-+ return crypto_aead_setkey(ctx->fback, (u8 *)key, len) ?:
-+ safexcel_aead_setkey(ctfm, key, len);
-+}
-+
-+static int safexcel_aead_fallback_setauthsize(struct crypto_aead *ctfm,
-+ unsigned int authsize)
-+{
-+ struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ /* Keep fallback cipher synchronized */
-+ return crypto_aead_setauthsize(ctx->fback, authsize);
-+}
-+
-+static int safexcel_aead_fallback_crypt(struct aead_request *req,
-+ enum safexcel_cipher_direction dir)
-+{
-+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
-+ struct crypto_tfm *tfm = crypto_aead_tfm(aead);
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+ struct aead_request *subreq = aead_request_ctx(req);
-+
-+ aead_request_set_tfm(subreq, ctx->fback);
-+ aead_request_set_callback(subreq, req->base.flags, req->base.complete,
-+ req->base.data);
-+ aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,
-+ req->iv);
-+ aead_request_set_ad(subreq, req->assoclen);
-+
-+ return (dir == SAFEXCEL_ENCRYPT) ?
-+ crypto_aead_encrypt(subreq) :
-+ crypto_aead_decrypt(subreq);
-+}
-+
-+static int safexcel_aead_sm4cbc_sm3_encrypt(struct aead_request *req)
-+{
-+ struct safexcel_cipher_req *creq = aead_request_ctx(req);
-+
-+ /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
-+ if (req->cryptlen & (SM4_BLOCK_SIZE - 1))
-+ return -EINVAL;
-+ else if (req->cryptlen || req->assoclen) /* If input length > 0 only */
-+ return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);
-+
-+ /* HW cannot do full (AAD+payload) zero length, use fallback */
-+ return safexcel_aead_fallback_crypt(req, SAFEXCEL_ENCRYPT);
-+}
-+
-+static int safexcel_aead_sm4cbc_sm3_decrypt(struct aead_request *req)
-+{
-+ struct safexcel_cipher_req *creq = aead_request_ctx(req);
-+ struct crypto_aead *tfm = crypto_aead_reqtfm(req);
-+
-+ /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
-+ if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1))
-+ return -EINVAL;
-+ else if (req->cryptlen > crypto_aead_authsize(tfm) || req->assoclen)
-+ /* If input length > 0 only */
-+ return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);
-+
-+ /* HW cannot do full (AAD+payload) zero length, use fallback */
-+ return safexcel_aead_fallback_crypt(req, SAFEXCEL_DECRYPT);
-+}
-+
-+static int safexcel_aead_sm4cbc_sm3_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_aead_fallback_cra_init(tfm);
-+ ctx->alg = SAFEXCEL_SM4;
-+ ctx->blocksz = SM4_BLOCK_SIZE;
-+ ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SM3;
-+ ctx->state_sz = SM3_DIGEST_SIZE;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_cbc_sm4 = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3,
-+ .alg.aead = {
-+ .setkey = safexcel_aead_fallback_setkey,
-+ .setauthsize = safexcel_aead_fallback_setauthsize,
-+ .encrypt = safexcel_aead_sm4cbc_sm3_encrypt,
-+ .decrypt = safexcel_aead_sm4cbc_sm3_decrypt,
-+ .ivsize = SM4_BLOCK_SIZE,
-+ .maxauthsize = SM3_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sm3),cbc(sm4))",
-+ .cra_driver_name = "safexcel-authenc-hmac-sm3-cbc-sm4",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY |
-+ CRYPTO_ALG_NEED_FALLBACK,
-+ .cra_blocksize = SM4_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_aead_sm4cbc_sm3_cra_init,
-+ .cra_exit = safexcel_aead_fallback_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_aead_sm4ctr_sha1_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_aead_sm4cbc_sha1_cra_init(tfm);
-+ ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_sm4 = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1,
-+ .alg.aead = {
-+ .setkey = safexcel_aead_setkey,
-+ .encrypt = safexcel_aead_encrypt,
-+ .decrypt = safexcel_aead_decrypt,
-+ .ivsize = CTR_RFC3686_IV_SIZE,
-+ .maxauthsize = SHA1_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha1),rfc3686(ctr(sm4)))",
-+ .cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-sm4",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_aead_sm4ctr_sha1_cra_init,
-+ .cra_exit = safexcel_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_aead_sm4ctr_sm3_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_aead_sm4cbc_sm3_cra_init(tfm);
-+ ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_ctr_sm4 = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3,
-+ .alg.aead = {
-+ .setkey = safexcel_aead_setkey,
-+ .encrypt = safexcel_aead_encrypt,
-+ .decrypt = safexcel_aead_decrypt,
-+ .ivsize = CTR_RFC3686_IV_SIZE,
-+ .maxauthsize = SM3_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sm3),rfc3686(ctr(sm4)))",
-+ .cra_driver_name = "safexcel-authenc-hmac-sm3-ctr-sm4",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_aead_sm4ctr_sm3_cra_init,
-+ .cra_exit = safexcel_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+static int safexcel_rfc4106_gcm_setkey(struct crypto_aead *ctfm, const u8 *key,
-+ unsigned int len)
-+{
-+ struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ /* last 4 bytes of key are the nonce! */
-+ ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE);
-+
-+ len -= CTR_RFC3686_NONCE_SIZE;
-+ return safexcel_aead_gcm_setkey(ctfm, key, len);
-+}
-+
-+static int safexcel_rfc4106_gcm_setauthsize(struct crypto_aead *tfm,
-+ unsigned int authsize)
-+{
-+ return crypto_rfc4106_check_authsize(authsize);
-+}
-+
-+static int safexcel_rfc4106_encrypt(struct aead_request *req)
-+{
-+ return crypto_ipsec_check_assoclen(req->assoclen) ?:
-+ safexcel_aead_encrypt(req);
-+}
-+
-+static int safexcel_rfc4106_decrypt(struct aead_request *req)
-+{
-+ return crypto_ipsec_check_assoclen(req->assoclen) ?:
-+ safexcel_aead_decrypt(req);
-+}
-+
-+static int safexcel_rfc4106_gcm_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+ int ret;
-+
-+ ret = safexcel_aead_gcm_cra_init(tfm);
-+ ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP;
-+ ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE;
-+ return ret;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_rfc4106_gcm = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH,
-+ .alg.aead = {
-+ .setkey = safexcel_rfc4106_gcm_setkey,
-+ .setauthsize = safexcel_rfc4106_gcm_setauthsize,
-+ .encrypt = safexcel_rfc4106_encrypt,
-+ .decrypt = safexcel_rfc4106_decrypt,
-+ .ivsize = GCM_RFC4106_IV_SIZE,
-+ .maxauthsize = GHASH_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "rfc4106(gcm(aes))",
-+ .cra_driver_name = "safexcel-rfc4106-gcm-aes",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_rfc4106_gcm_cra_init,
-+ .cra_exit = safexcel_aead_gcm_cra_exit,
-+ },
-+ },
-+};
-+
-+static int safexcel_rfc4543_gcm_setauthsize(struct crypto_aead *tfm,
-+ unsigned int authsize)
-+{
-+ if (authsize != GHASH_DIGEST_SIZE)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static int safexcel_rfc4543_gcm_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+ int ret;
-+
-+ ret = safexcel_aead_gcm_cra_init(tfm);
-+ ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP_GMAC;
-+ return ret;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_rfc4543_gcm = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH,
-+ .alg.aead = {
-+ .setkey = safexcel_rfc4106_gcm_setkey,
-+ .setauthsize = safexcel_rfc4543_gcm_setauthsize,
-+ .encrypt = safexcel_rfc4106_encrypt,
-+ .decrypt = safexcel_rfc4106_decrypt,
-+ .ivsize = GCM_RFC4543_IV_SIZE,
-+ .maxauthsize = GHASH_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "rfc4543(gcm(aes))",
-+ .cra_driver_name = "safexcel-rfc4543-gcm-aes",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_rfc4543_gcm_cra_init,
-+ .cra_exit = safexcel_aead_gcm_cra_exit,
-+ },
-+ },
-+};
-+
-+static int safexcel_rfc4309_ccm_setkey(struct crypto_aead *ctfm, const u8 *key,
-+ unsigned int len)
-+{
-+ struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ /* First byte of the nonce = L = always 3 for RFC4309 (4 byte ctr) */
-+ *(u8 *)&ctx->nonce = EIP197_AEAD_IPSEC_COUNTER_SIZE - 1;
-+ /* last 3 bytes of key are the nonce! */
-+ memcpy((u8 *)&ctx->nonce + 1, key + len -
-+ EIP197_AEAD_IPSEC_CCM_NONCE_SIZE,
-+ EIP197_AEAD_IPSEC_CCM_NONCE_SIZE);
-+
-+ len -= EIP197_AEAD_IPSEC_CCM_NONCE_SIZE;
-+ return safexcel_aead_ccm_setkey(ctfm, key, len);
-+}
-+
-+static int safexcel_rfc4309_ccm_setauthsize(struct crypto_aead *tfm,
-+ unsigned int authsize)
-+{
-+ /* Borrowed from crypto/ccm.c */
-+ switch (authsize) {
-+ case 8:
-+ case 12:
-+ case 16:
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int safexcel_rfc4309_ccm_encrypt(struct aead_request *req)
-+{
-+ struct safexcel_cipher_req *creq = aead_request_ctx(req);
-+
-+ /* Borrowed from crypto/ccm.c */
-+ if (req->assoclen != 16 && req->assoclen != 20)
-+ return -EINVAL;
-+
-+ return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);
-+}
-+
-+static int safexcel_rfc4309_ccm_decrypt(struct aead_request *req)
-+{
-+ struct safexcel_cipher_req *creq = aead_request_ctx(req);
-+
-+ /* Borrowed from crypto/ccm.c */
-+ if (req->assoclen != 16 && req->assoclen != 20)
-+ return -EINVAL;
-+
-+ return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);
-+}
-+
-+static int safexcel_rfc4309_ccm_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
-+ int ret;
-+
-+ ret = safexcel_aead_ccm_cra_init(tfm);
-+ ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP;
-+ ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE;
-+ return ret;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_rfc4309_ccm = {
-+ .type = SAFEXCEL_ALG_TYPE_AEAD,
-+ .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL,
-+ .alg.aead = {
-+ .setkey = safexcel_rfc4309_ccm_setkey,
-+ .setauthsize = safexcel_rfc4309_ccm_setauthsize,
-+ .encrypt = safexcel_rfc4309_ccm_encrypt,
-+ .decrypt = safexcel_rfc4309_ccm_decrypt,
-+ .ivsize = EIP197_AEAD_IPSEC_IV_SIZE,
-+ .maxauthsize = AES_BLOCK_SIZE,
-+ .base = {
-+ .cra_name = "rfc4309(ccm(aes))",
-+ .cra_driver_name = "safexcel-rfc4309-ccm-aes",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = safexcel_rfc4309_ccm_cra_init,
-+ .cra_exit = safexcel_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
- },
- };
---- a/drivers/crypto/inside-secure/safexcel.h
-+++ b/drivers/crypto/inside-secure/safexcel.h
-@@ -17,8 +17,11 @@
- #define EIP197_HIA_VERSION_BE 0xca35
- #define EIP197_HIA_VERSION_LE 0x35ca
- #define EIP97_VERSION_LE 0x9e61
-+#define EIP196_VERSION_LE 0x3bc4
- #define EIP197_VERSION_LE 0x3ac5
- #define EIP96_VERSION_LE 0x9f60
-+#define EIP201_VERSION_LE 0x36c9
-+#define EIP206_VERSION_LE 0x31ce
- #define EIP197_REG_LO16(reg) (reg & 0xffff)
- #define EIP197_REG_HI16(reg) ((reg >> 16) & 0xffff)
- #define EIP197_VERSION_MASK(reg) ((reg >> 16) & 0xfff)
-@@ -26,12 +29,23 @@
- ((reg >> 4) & 0xf0) | \
- ((reg >> 12) & 0xf))
-
-+/* EIP197 HIA OPTIONS ENCODING */
-+#define EIP197_HIA_OPT_HAS_PE_ARB BIT(29)
-+
-+/* EIP206 OPTIONS ENCODING */
-+#define EIP206_OPT_ICE_TYPE(n) ((n>>8)&3)
-+
-+/* EIP197 OPTIONS ENCODING */
-+#define EIP197_OPT_HAS_TRC BIT(31)
-+
- /* Static configuration */
- #define EIP197_DEFAULT_RING_SIZE 400
--#define EIP197_MAX_TOKENS 18
-+#define EIP197_EMB_TOKENS 4 /* Pad CD to 16 dwords */
-+#define EIP197_MAX_TOKENS 16
- #define EIP197_MAX_RINGS 4
- #define EIP197_FETCH_DEPTH 2
- #define EIP197_MAX_BATCH_SZ 64
-+#define EIP197_MAX_RING_AIC 14
-
- #define EIP197_GFP_FLAGS(base) ((base).flags & CRYPTO_TFM_REQ_MAY_SLEEP ? \
- GFP_KERNEL : GFP_ATOMIC)
-@@ -138,6 +152,7 @@
- #define EIP197_HIA_AIC_R_ENABLED_STAT(r) (0xe010 - EIP197_HIA_AIC_R_OFF(r))
- #define EIP197_HIA_AIC_R_ACK(r) (0xe010 - EIP197_HIA_AIC_R_OFF(r))
- #define EIP197_HIA_AIC_R_ENABLE_CLR(r) (0xe014 - EIP197_HIA_AIC_R_OFF(r))
-+#define EIP197_HIA_AIC_R_VERSION(r) (0xe01c - EIP197_HIA_AIC_R_OFF(r))
- #define EIP197_HIA_AIC_G_ENABLE_CTRL 0xf808
- #define EIP197_HIA_AIC_G_ENABLED_STAT 0xf810
- #define EIP197_HIA_AIC_G_ACK 0xf810
-@@ -157,12 +172,16 @@
- #define EIP197_PE_EIP96_FUNCTION_EN(n) (0x1004 + (0x2000 * (n)))
- #define EIP197_PE_EIP96_CONTEXT_CTRL(n) (0x1008 + (0x2000 * (n)))
- #define EIP197_PE_EIP96_CONTEXT_STAT(n) (0x100c + (0x2000 * (n)))
-+#define EIP197_PE_EIP96_TOKEN_CTRL2(n) (0x102c + (0x2000 * (n)))
- #define EIP197_PE_EIP96_FUNCTION2_EN(n) (0x1030 + (0x2000 * (n)))
- #define EIP197_PE_EIP96_OPTIONS(n) (0x13f8 + (0x2000 * (n)))
- #define EIP197_PE_EIP96_VERSION(n) (0x13fc + (0x2000 * (n)))
- #define EIP197_PE_OUT_DBUF_THRES(n) (0x1c00 + (0x2000 * (n)))
- #define EIP197_PE_OUT_TBUF_THRES(n) (0x1d00 + (0x2000 * (n)))
-+#define EIP197_PE_OPTIONS(n) (0x1ff8 + (0x2000 * (n)))
-+#define EIP197_PE_VERSION(n) (0x1ffc + (0x2000 * (n)))
- #define EIP197_MST_CTRL 0xfff4
-+#define EIP197_OPTIONS 0xfff8
- #define EIP197_VERSION 0xfffc
-
- /* EIP197-specific registers, no indirection */
-@@ -178,6 +197,7 @@
- #define EIP197_TRC_ECCADMINSTAT 0xf0838
- #define EIP197_TRC_ECCDATASTAT 0xf083c
- #define EIP197_TRC_ECCDATA 0xf0840
-+#define EIP197_STRC_CONFIG 0xf43f0
- #define EIP197_FLUE_CACHEBASE_LO(n) (0xf6000 + (32 * (n)))
- #define EIP197_FLUE_CACHEBASE_HI(n) (0xf6004 + (32 * (n)))
- #define EIP197_FLUE_CONFIG(n) (0xf6010 + (32 * (n)))
-@@ -188,6 +208,7 @@
-
- /* EIP197_HIA_xDR_DESC_SIZE */
- #define EIP197_xDR_DESC_MODE_64BIT BIT(31)
-+#define EIP197_CDR_DESC_MODE_ADCP BIT(30)
-
- /* EIP197_HIA_xDR_DMA_CFG */
- #define EIP197_HIA_xDR_WR_RES_BUF BIT(22)
-@@ -213,7 +234,6 @@
- /* EIP197_HIA_xDR_PROC_COUNT */
- #define EIP197_xDR_PROC_xD_PKT_OFFSET 24
- #define EIP197_xDR_PROC_xD_PKT_MASK GENMASK(6, 0)
--#define EIP197_xDR_PROC_xD_COUNT(n) ((n) << 2)
- #define EIP197_xDR_PROC_xD_PKT(n) ((n) << 24)
- #define EIP197_xDR_PROC_CLR_COUNT BIT(31)
-
-@@ -228,6 +248,8 @@
- #define EIP197_HIA_RA_PE_CTRL_EN BIT(30)
-
- /* EIP197_HIA_OPTIONS */
-+#define EIP197_N_RINGS_OFFSET 0
-+#define EIP197_N_RINGS_MASK GENMASK(3, 0)
- #define EIP197_N_PES_OFFSET 4
- #define EIP197_N_PES_MASK GENMASK(4, 0)
- #define EIP97_N_PES_MASK GENMASK(2, 0)
-@@ -237,13 +259,13 @@
- #define EIP197_CFSIZE_OFFSET 9
- #define EIP197_CFSIZE_ADJUST 4
- #define EIP97_CFSIZE_OFFSET 8
--#define EIP197_CFSIZE_MASK GENMASK(3, 0)
--#define EIP97_CFSIZE_MASK GENMASK(4, 0)
-+#define EIP197_CFSIZE_MASK GENMASK(2, 0)
-+#define EIP97_CFSIZE_MASK GENMASK(3, 0)
- #define EIP197_RFSIZE_OFFSET 12
- #define EIP197_RFSIZE_ADJUST 4
- #define EIP97_RFSIZE_OFFSET 12
--#define EIP197_RFSIZE_MASK GENMASK(3, 0)
--#define EIP97_RFSIZE_MASK GENMASK(4, 0)
-+#define EIP197_RFSIZE_MASK GENMASK(2, 0)
-+#define EIP97_RFSIZE_MASK GENMASK(3, 0)
-
- /* EIP197_HIA_AIC_R_ENABLE_CTRL */
- #define EIP197_CDR_IRQ(n) BIT((n) * 2)
-@@ -257,9 +279,9 @@
- #define EIP197_HIA_DxE_CFG_MIN_CTRL_SIZE(n) ((n) << 16)
- #define EIP197_HIA_DxE_CFG_CTRL_CACHE_CTRL(n) (((n) & 0x7) << 20)
- #define EIP197_HIA_DxE_CFG_MAX_CTRL_SIZE(n) ((n) << 24)
--#define EIP197_HIA_DFE_CFG_DIS_DEBUG (BIT(31) | BIT(29))
-+#define EIP197_HIA_DFE_CFG_DIS_DEBUG GENMASK(31, 29)
- #define EIP197_HIA_DSE_CFG_EN_SINGLE_WR BIT(29)
--#define EIP197_HIA_DSE_CFG_DIS_DEBUG BIT(31)
-+#define EIP197_HIA_DSE_CFG_DIS_DEBUG GENMASK(31, 30)
-
- /* EIP197_HIA_DFE/DSE_THR_CTRL */
- #define EIP197_DxE_THR_CTRL_EN BIT(30)
-@@ -327,13 +349,21 @@
- #define EIP197_ADDRESS_MODE BIT(8)
- #define EIP197_CONTROL_MODE BIT(9)
-
-+/* EIP197_PE_EIP96_TOKEN_CTRL2 */
-+#define EIP197_PE_EIP96_TOKEN_CTRL2_CTX_DONE BIT(3)
-+
-+/* EIP197_STRC_CONFIG */
-+#define EIP197_STRC_CONFIG_INIT BIT(31)
-+#define EIP197_STRC_CONFIG_LARGE_REC(s) (s<<8)
-+#define EIP197_STRC_CONFIG_SMALL_REC(s) (s<<0)
-+
- /* EIP197_FLUE_CONFIG */
- #define EIP197_FLUE_CONFIG_MAGIC 0xc7000004
-
- /* Context Control */
- struct safexcel_context_record {
-- u32 control0;
-- u32 control1;
-+ __le32 control0;
-+ __le32 control1;
-
- __le32 data[40];
- } __packed;
-@@ -358,10 +388,14 @@ struct safexcel_context_record {
- #define CONTEXT_CONTROL_CRYPTO_ALG_AES128 (0x5 << 17)
- #define CONTEXT_CONTROL_CRYPTO_ALG_AES192 (0x6 << 17)
- #define CONTEXT_CONTROL_CRYPTO_ALG_AES256 (0x7 << 17)
-+#define CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20 (0x8 << 17)
-+#define CONTEXT_CONTROL_CRYPTO_ALG_SM4 (0xd << 17)
-+#define CONTEXT_CONTROL_DIGEST_INITIAL (0x0 << 21)
- #define CONTEXT_CONTROL_DIGEST_PRECOMPUTED (0x1 << 21)
- #define CONTEXT_CONTROL_DIGEST_XCM (0x2 << 21)
- #define CONTEXT_CONTROL_DIGEST_HMAC (0x3 << 21)
- #define CONTEXT_CONTROL_CRYPTO_ALG_MD5 (0x0 << 23)
-+#define CONTEXT_CONTROL_CRYPTO_ALG_CRC32 (0x0 << 23)
- #define CONTEXT_CONTROL_CRYPTO_ALG_SHA1 (0x2 << 23)
- #define CONTEXT_CONTROL_CRYPTO_ALG_SHA224 (0x4 << 23)
- #define CONTEXT_CONTROL_CRYPTO_ALG_SHA256 (0x3 << 23)
-@@ -371,17 +405,25 @@ struct safexcel_context_record {
- #define CONTEXT_CONTROL_CRYPTO_ALG_XCBC128 (0x1 << 23)
- #define CONTEXT_CONTROL_CRYPTO_ALG_XCBC192 (0x2 << 23)
- #define CONTEXT_CONTROL_CRYPTO_ALG_XCBC256 (0x3 << 23)
-+#define CONTEXT_CONTROL_CRYPTO_ALG_SM3 (0x7 << 23)
-+#define CONTEXT_CONTROL_CRYPTO_ALG_SHA3_256 (0xb << 23)
-+#define CONTEXT_CONTROL_CRYPTO_ALG_SHA3_224 (0xc << 23)
-+#define CONTEXT_CONTROL_CRYPTO_ALG_SHA3_512 (0xd << 23)
-+#define CONTEXT_CONTROL_CRYPTO_ALG_SHA3_384 (0xe << 23)
-+#define CONTEXT_CONTROL_CRYPTO_ALG_POLY1305 (0xf << 23)
- #define CONTEXT_CONTROL_INV_FR (0x5 << 24)
- #define CONTEXT_CONTROL_INV_TR (0x6 << 24)
-
- /* control1 */
- #define CONTEXT_CONTROL_CRYPTO_MODE_ECB (0 << 0)
- #define CONTEXT_CONTROL_CRYPTO_MODE_CBC (1 << 0)
-+#define CONTEXT_CONTROL_CHACHA20_MODE_256_32 (2 << 0)
- #define CONTEXT_CONTROL_CRYPTO_MODE_OFB (4 << 0)
- #define CONTEXT_CONTROL_CRYPTO_MODE_CFB (5 << 0)
- #define CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD (6 << 0)
- #define CONTEXT_CONTROL_CRYPTO_MODE_XTS (7 << 0)
- #define CONTEXT_CONTROL_CRYPTO_MODE_XCM ((6 << 0) | BIT(17))
-+#define CONTEXT_CONTROL_CHACHA20_MODE_CALC_OTK (12 << 0)
- #define CONTEXT_CONTROL_IV0 BIT(5)
- #define CONTEXT_CONTROL_IV1 BIT(6)
- #define CONTEXT_CONTROL_IV2 BIT(7)
-@@ -394,6 +436,13 @@ struct safexcel_context_record {
- #define EIP197_XCM_MODE_GCM 1
- #define EIP197_XCM_MODE_CCM 2
-
-+#define EIP197_AEAD_TYPE_IPSEC_ESP 2
-+#define EIP197_AEAD_TYPE_IPSEC_ESP_GMAC 3
-+#define EIP197_AEAD_IPSEC_IV_SIZE 8
-+#define EIP197_AEAD_IPSEC_NONCE_SIZE 4
-+#define EIP197_AEAD_IPSEC_COUNTER_SIZE 4
-+#define EIP197_AEAD_IPSEC_CCM_NONCE_SIZE 3
-+
- /* The hash counter given to the engine in the context has a granularity of
- * 64 bits.
- */
-@@ -423,6 +472,8 @@ struct safexcel_context_record {
- #define EIP197_TRC_PARAMS2_RC_SZ_SMALL(n) ((n) << 18)
-
- /* Cache helpers */
-+#define EIP197_MIN_DSIZE 1024
-+#define EIP197_MIN_ASIZE 8
- #define EIP197_CS_TRC_REC_WC 64
- #define EIP197_CS_RC_SIZE (4 * sizeof(u32))
- #define EIP197_CS_RC_NEXT(x) (x)
-@@ -447,7 +498,7 @@ struct result_data_desc {
- u16 application_id;
- u16 rsvd1;
-
-- u32 rsvd2;
-+ u32 rsvd2[5];
- } __packed;
-
-
-@@ -465,16 +516,15 @@ struct safexcel_result_desc {
-
- u32 data_lo;
- u32 data_hi;
--
-- struct result_data_desc result_data;
- } __packed;
-
- /*
- * The EIP(1)97 only needs to fetch the descriptor part of
- * the result descriptor, not the result token part!
- */
--#define EIP197_RD64_FETCH_SIZE ((sizeof(struct safexcel_result_desc) -\
-- sizeof(struct result_data_desc)) /\
-+#define EIP197_RD64_FETCH_SIZE (sizeof(struct safexcel_result_desc) /\
-+ sizeof(u32))
-+#define EIP197_RD64_RESULT_SIZE (sizeof(struct result_data_desc) /\
- sizeof(u32))
-
- struct safexcel_token {
-@@ -505,6 +555,8 @@ static inline void eip197_noop_token(str
- {
- token->opcode = EIP197_TOKEN_OPCODE_NOOP;
- token->packet_length = BIT(2);
-+ token->stat = 0;
-+ token->instructions = 0;
- }
-
- /* Instructions */
-@@ -526,14 +578,13 @@ struct safexcel_control_data_desc {
- u16 application_id;
- u16 rsvd;
-
-- u8 refresh:2;
-- u32 context_lo:30;
-+ u32 context_lo;
- u32 context_hi;
-
- u32 control0;
- u32 control1;
-
-- u32 token[EIP197_MAX_TOKENS];
-+ u32 token[EIP197_EMB_TOKENS];
- } __packed;
-
- #define EIP197_OPTION_MAGIC_VALUE BIT(0)
-@@ -543,7 +594,10 @@ struct safexcel_control_data_desc {
- #define EIP197_OPTION_2_TOKEN_IV_CMD GENMASK(11, 10)
- #define EIP197_OPTION_4_TOKEN_IV_CMD GENMASK(11, 9)
-
-+#define EIP197_TYPE_BCLA 0x0
- #define EIP197_TYPE_EXTENDED 0x3
-+#define EIP197_CONTEXT_SMALL 0x2
-+#define EIP197_CONTEXT_SIZE_MASK 0x3
-
- /* Basic Command Descriptor format */
- struct safexcel_command_desc {
-@@ -551,16 +605,22 @@ struct safexcel_command_desc {
- u8 rsvd0:5;
- u8 last_seg:1;
- u8 first_seg:1;
-- u16 additional_cdata_size:8;
-+ u8 additional_cdata_size:8;
-
- u32 rsvd1;
-
- u32 data_lo;
- u32 data_hi;
-
-+ u32 atok_lo;
-+ u32 atok_hi;
-+
- struct safexcel_control_data_desc control_data;
- } __packed;
-
-+#define EIP197_CD64_FETCH_SIZE (sizeof(struct safexcel_command_desc) /\
-+ sizeof(u32))
-+
- /*
- * Internal structures & functions
- */
-@@ -578,15 +638,20 @@ enum eip197_fw {
-
- struct safexcel_desc_ring {
- void *base;
-+ void *shbase;
- void *base_end;
-+ void *shbase_end;
- dma_addr_t base_dma;
-+ dma_addr_t shbase_dma;
-
- /* write and read pointers */
- void *write;
-+ void *shwrite;
- void *read;
-
- /* descriptor element offset */
-- unsigned offset;
-+ unsigned int offset;
-+ unsigned int shoffset;
- };
-
- enum safexcel_alg_type {
-@@ -601,9 +666,11 @@ struct safexcel_config {
-
- u32 cd_size;
- u32 cd_offset;
-+ u32 cdsh_offset;
-
- u32 rd_size;
- u32 rd_offset;
-+ u32 res_offset;
- };
-
- struct safexcel_work_data {
-@@ -654,6 +721,12 @@ enum safexcel_eip_version {
- /* Priority we use for advertising our algorithms */
- #define SAFEXCEL_CRA_PRIORITY 300
-
-+/* SM3 digest result for zero length message */
-+#define EIP197_SM3_ZEROM_HASH "\x1A\xB2\x1D\x83\x55\xCF\xA1\x7F" \
-+ "\x8E\x61\x19\x48\x31\xE8\x1A\x8F" \
-+ "\x22\xBE\xC8\xC7\x28\xFE\xFB\x74" \
-+ "\x7E\xD0\x35\xEB\x50\x82\xAA\x2B"
-+
- /* EIP algorithm presence flags */
- enum safexcel_eip_algorithms {
- SAFEXCEL_ALG_BC0 = BIT(5),
-@@ -697,16 +770,23 @@ struct safexcel_register_offsets {
- enum safexcel_flags {
- EIP197_TRC_CACHE = BIT(0),
- SAFEXCEL_HW_EIP197 = BIT(1),
-+ EIP197_PE_ARB = BIT(2),
-+ EIP197_ICE = BIT(3),
-+ EIP197_SIMPLE_TRC = BIT(4),
- };
-
- struct safexcel_hwconfig {
- enum safexcel_eip_algorithms algo_flags;
- int hwver;
- int hiaver;
-+ int ppver;
- int pever;
- int hwdataw;
- int hwcfsize;
- int hwrfsize;
-+ int hwnumpes;
-+ int hwnumrings;
-+ int hwnumraic;
- };
-
- struct safexcel_crypto_priv {
-@@ -778,7 +858,7 @@ struct safexcel_inv_result {
-
- void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring);
- int safexcel_rdesc_check_errors(struct safexcel_crypto_priv *priv,
-- struct safexcel_result_desc *rdesc);
-+ void *rdp);
- void safexcel_complete(struct safexcel_crypto_priv *priv, int ring);
- int safexcel_invalidate_cache(struct crypto_async_request *async,
- struct safexcel_crypto_priv *priv,
-@@ -797,7 +877,8 @@ struct safexcel_command_desc *safexcel_a
- bool first, bool last,
- dma_addr_t data, u32 len,
- u32 full_data_len,
-- dma_addr_t context);
-+ dma_addr_t context,
-+ struct safexcel_token **atoken);
- struct safexcel_result_desc *safexcel_add_rdesc(struct safexcel_crypto_priv *priv,
- int ring_id,
- bool first, bool last,
-@@ -853,5 +934,43 @@ extern struct safexcel_alg_template safe
- extern struct safexcel_alg_template safexcel_alg_xts_aes;
- extern struct safexcel_alg_template safexcel_alg_gcm;
- extern struct safexcel_alg_template safexcel_alg_ccm;
-+extern struct safexcel_alg_template safexcel_alg_crc32;
-+extern struct safexcel_alg_template safexcel_alg_cbcmac;
-+extern struct safexcel_alg_template safexcel_alg_xcbcmac;
-+extern struct safexcel_alg_template safexcel_alg_cmac;
-+extern struct safexcel_alg_template safexcel_alg_chacha20;
-+extern struct safexcel_alg_template safexcel_alg_chachapoly;
-+extern struct safexcel_alg_template safexcel_alg_chachapoly_esp;
-+extern struct safexcel_alg_template safexcel_alg_sm3;
-+extern struct safexcel_alg_template safexcel_alg_hmac_sm3;
-+extern struct safexcel_alg_template safexcel_alg_ecb_sm4;
-+extern struct safexcel_alg_template safexcel_alg_cbc_sm4;
-+extern struct safexcel_alg_template safexcel_alg_ofb_sm4;
-+extern struct safexcel_alg_template safexcel_alg_cfb_sm4;
-+extern struct safexcel_alg_template safexcel_alg_ctr_sm4;
-+extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_sm4;
-+extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_cbc_sm4;
-+extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_sm4;
-+extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_ctr_sm4;
-+extern struct safexcel_alg_template safexcel_alg_sha3_224;
-+extern struct safexcel_alg_template safexcel_alg_sha3_256;
-+extern struct safexcel_alg_template safexcel_alg_sha3_384;
-+extern struct safexcel_alg_template safexcel_alg_sha3_512;
-+extern struct safexcel_alg_template safexcel_alg_hmac_sha3_224;
-+extern struct safexcel_alg_template safexcel_alg_hmac_sha3_256;
-+extern struct safexcel_alg_template safexcel_alg_hmac_sha3_384;
-+extern struct safexcel_alg_template safexcel_alg_hmac_sha3_512;
-+extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des;
-+extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des3_ede;
-+extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des3_ede;
-+extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des3_ede;
-+extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des3_ede;
-+extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des;
-+extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des;
-+extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des;
-+extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des;
-+extern struct safexcel_alg_template safexcel_alg_rfc4106_gcm;
-+extern struct safexcel_alg_template safexcel_alg_rfc4543_gcm;
-+extern struct safexcel_alg_template safexcel_alg_rfc4309_ccm;
-
- #endif
---- a/drivers/crypto/inside-secure/safexcel_hash.c
-+++ b/drivers/crypto/inside-secure/safexcel_hash.c
-@@ -5,9 +5,13 @@
- * Antoine Tenart <antoine.tenart@free-electrons.com>
- */
-
-+#include <crypto/aes.h>
- #include <crypto/hmac.h>
- #include <crypto/md5.h>
- #include <crypto/sha.h>
-+#include <crypto/sha3.h>
-+#include <crypto/skcipher.h>
-+#include <crypto/sm3.h>
- #include <linux/device.h>
- #include <linux/dma-mapping.h>
- #include <linux/dmapool.h>
-@@ -19,9 +23,19 @@ struct safexcel_ahash_ctx {
- struct safexcel_crypto_priv *priv;
-
- u32 alg;
--
-- u32 ipad[SHA512_DIGEST_SIZE / sizeof(u32)];
-- u32 opad[SHA512_DIGEST_SIZE / sizeof(u32)];
-+ u8 key_sz;
-+ bool cbcmac;
-+ bool do_fallback;
-+ bool fb_init_done;
-+ bool fb_do_setkey;
-+
-+ __le32 ipad[SHA3_512_BLOCK_SIZE / sizeof(__le32)];
-+ __le32 opad[SHA3_512_BLOCK_SIZE / sizeof(__le32)];
-+
-+ struct crypto_cipher *kaes;
-+ struct crypto_ahash *fback;
-+ struct crypto_shash *shpre;
-+ struct shash_desc *shdesc;
- };
-
- struct safexcel_ahash_req {
-@@ -31,6 +45,8 @@ struct safexcel_ahash_req {
- bool needs_inv;
- bool hmac_zlen;
- bool len_is_le;
-+ bool not_first;
-+ bool xcbcmac;
-
- int nents;
- dma_addr_t result_dma;
-@@ -39,7 +55,9 @@ struct safexcel_ahash_req {
-
- u8 state_sz; /* expected state size, only set once */
- u8 block_sz; /* block size, only set once */
-- u32 state[SHA512_DIGEST_SIZE / sizeof(u32)] __aligned(sizeof(u32));
-+ u8 digest_sz; /* output digest size, only set once */
-+ __le32 state[SHA3_512_BLOCK_SIZE /
-+ sizeof(__le32)] __aligned(sizeof(__le32));
-
- u64 len;
- u64 processed;
-@@ -57,22 +75,36 @@ static inline u64 safexcel_queued_len(st
- }
-
- static void safexcel_hash_token(struct safexcel_command_desc *cdesc,
-- u32 input_length, u32 result_length)
-+ u32 input_length, u32 result_length,
-+ bool cbcmac)
- {
- struct safexcel_token *token =
- (struct safexcel_token *)cdesc->control_data.token;
-
- token[0].opcode = EIP197_TOKEN_OPCODE_DIRECTION;
- token[0].packet_length = input_length;
-- token[0].stat = EIP197_TOKEN_STAT_LAST_HASH;
- token[0].instructions = EIP197_TOKEN_INS_TYPE_HASH;
-
-- token[1].opcode = EIP197_TOKEN_OPCODE_INSERT;
-- token[1].packet_length = result_length;
-- token[1].stat = EIP197_TOKEN_STAT_LAST_HASH |
-+ input_length &= 15;
-+ if (unlikely(cbcmac && input_length)) {
-+ token[0].stat = 0;
-+ token[1].opcode = EIP197_TOKEN_OPCODE_INSERT;
-+ token[1].packet_length = 16 - input_length;
-+ token[1].stat = EIP197_TOKEN_STAT_LAST_HASH;
-+ token[1].instructions = EIP197_TOKEN_INS_TYPE_HASH;
-+ } else {
-+ token[0].stat = EIP197_TOKEN_STAT_LAST_HASH;
-+ eip197_noop_token(&token[1]);
-+ }
-+
-+ token[2].opcode = EIP197_TOKEN_OPCODE_INSERT;
-+ token[2].stat = EIP197_TOKEN_STAT_LAST_HASH |
- EIP197_TOKEN_STAT_LAST_PACKET;
-- token[1].instructions = EIP197_TOKEN_INS_TYPE_OUTPUT |
-+ token[2].packet_length = result_length;
-+ token[2].instructions = EIP197_TOKEN_INS_TYPE_OUTPUT |
- EIP197_TOKEN_INS_INSERT_HASH_DIGEST;
-+
-+ eip197_noop_token(&token[3]);
- }
-
- static void safexcel_context_control(struct safexcel_ahash_ctx *ctx,
-@@ -82,29 +114,49 @@ static void safexcel_context_control(str
- struct safexcel_crypto_priv *priv = ctx->priv;
- u64 count = 0;
-
-- cdesc->control_data.control0 |= ctx->alg;
-+ cdesc->control_data.control0 = ctx->alg;
-+ cdesc->control_data.control1 = 0;
-
- /*
- * Copy the input digest if needed, and setup the context
- * fields. Do this now as we need it to setup the first command
- * descriptor.
- */
-- if (!req->processed) {
-- /* First - and possibly only - block of basic hash only */
-- if (req->finish) {
-+ if (unlikely(req->digest == CONTEXT_CONTROL_DIGEST_XCM)) {
-+ if (req->xcbcmac)
-+ memcpy(ctx->base.ctxr->data, ctx->ipad, ctx->key_sz);
-+ else
-+ memcpy(ctx->base.ctxr->data, req->state, req->state_sz);
-+
-+ if (!req->finish && req->xcbcmac)
-+ cdesc->control_data.control0 |=
-+ CONTEXT_CONTROL_DIGEST_XCM |
-+ CONTEXT_CONTROL_TYPE_HASH_OUT |
-+ CONTEXT_CONTROL_NO_FINISH_HASH |
-+ CONTEXT_CONTROL_SIZE(req->state_sz /
-+ sizeof(u32));
-+ else
- cdesc->control_data.control0 |=
-+ CONTEXT_CONTROL_DIGEST_XCM |
-+ CONTEXT_CONTROL_TYPE_HASH_OUT |
-+ CONTEXT_CONTROL_SIZE(req->state_sz /
-+ sizeof(u32));
-+ return;
-+ } else if (!req->processed) {
-+ /* First - and possibly only - block of basic hash only */
-+ if (req->finish)
-+ cdesc->control_data.control0 |= req->digest |
- CONTEXT_CONTROL_TYPE_HASH_OUT |
- CONTEXT_CONTROL_RESTART_HASH |
- /* ensure its not 0! */
- CONTEXT_CONTROL_SIZE(1);
-- } else {
-- cdesc->control_data.control0 |=
-+ else
-+ cdesc->control_data.control0 |= req->digest |
- CONTEXT_CONTROL_TYPE_HASH_OUT |
- CONTEXT_CONTROL_RESTART_HASH |
- CONTEXT_CONTROL_NO_FINISH_HASH |
- /* ensure its not 0! */
- CONTEXT_CONTROL_SIZE(1);
-- }
- return;
- }
-
-@@ -204,7 +256,7 @@ static int safexcel_handle_req_result(st
- }
-
- if (sreq->result_dma) {
-- dma_unmap_single(priv->dev, sreq->result_dma, sreq->state_sz,
-+ dma_unmap_single(priv->dev, sreq->result_dma, sreq->digest_sz,
- DMA_FROM_DEVICE);
- sreq->result_dma = 0;
- }
-@@ -223,14 +275,15 @@ static int safexcel_handle_req_result(st
- memcpy(sreq->cache, sreq->state,
- crypto_ahash_digestsize(ahash));
-
-- memcpy(sreq->state, ctx->opad, sreq->state_sz);
-+ memcpy(sreq->state, ctx->opad, sreq->digest_sz);
-
- sreq->len = sreq->block_sz +
- crypto_ahash_digestsize(ahash);
- sreq->processed = sreq->block_sz;
- sreq->hmac = 0;
-
-- ctx->base.needs_inv = true;
-+ if (priv->flags & EIP197_TRC_CACHE)
-+ ctx->base.needs_inv = true;
- areq->nbytes = 0;
- safexcel_ahash_enqueue(areq);
-
-@@ -238,8 +291,14 @@ static int safexcel_handle_req_result(st
- return 1;
- }
-
-- memcpy(areq->result, sreq->state,
-- crypto_ahash_digestsize(ahash));
-+ if (unlikely(sreq->digest == CONTEXT_CONTROL_DIGEST_XCM &&
-+ ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_CRC32)) {
-+ /* Undo final XOR with 0xffffffff ...*/
-+ *(__le32 *)areq->result = ~sreq->state[0];
-+ } else {
-+ memcpy(areq->result, sreq->state,
-+ crypto_ahash_digestsize(ahash));
-+ }
- }
-
- cache_len = safexcel_queued_len(sreq);
-@@ -261,10 +320,11 @@ static int safexcel_ahash_send_req(struc
- struct safexcel_command_desc *cdesc, *first_cdesc = NULL;
- struct safexcel_result_desc *rdesc;
- struct scatterlist *sg;
-- int i, extra = 0, n_cdesc = 0, ret = 0;
-- u64 queued, len, cache_len;
-+ struct safexcel_token *dmmy;
-+ int i, extra = 0, n_cdesc = 0, ret = 0, cache_len, skip = 0;
-+ u64 queued, len;
-
-- queued = len = safexcel_queued_len(req);
-+ queued = safexcel_queued_len(req);
- if (queued <= HASH_CACHE_SIZE)
- cache_len = queued;
- else
-@@ -287,15 +347,52 @@ static int safexcel_ahash_send_req(struc
- areq->nbytes - extra);
-
- queued -= extra;
-- len -= extra;
-
- if (!queued) {
- *commands = 0;
- *results = 0;
- return 0;
- }
-+
-+ extra = 0;
-+ }
-+
-+ if (unlikely(req->xcbcmac && req->processed > AES_BLOCK_SIZE)) {
-+ if (unlikely(cache_len < AES_BLOCK_SIZE)) {
-+ /*
-+ * Cache contains less than 1 full block, complete.
-+ */
-+ extra = AES_BLOCK_SIZE - cache_len;
-+ if (queued > cache_len) {
-+ /* More data follows: borrow bytes */
-+ u64 tmp = queued - cache_len;
-+
-+ skip = min_t(u64, tmp, extra);
-+ sg_pcopy_to_buffer(areq->src,
-+ sg_nents(areq->src),
-+ req->cache + cache_len,
-+ skip, 0);
-+ }
-+ extra -= skip;
-+ memset(req->cache + cache_len + skip, 0, extra);
-+ if (!ctx->cbcmac && extra) {
-+ // 10- padding for XCBCMAC & CMAC
-+ req->cache[cache_len + skip] = 0x80;
-+ // HW will use K2 iso K3 - compensate!
-+ for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++)
-+ ((__be32 *)req->cache)[i] ^=
-+ cpu_to_be32(le32_to_cpu(
-+ ctx->ipad[i] ^ ctx->ipad[i + 4]));
-+ }
-+ cache_len = AES_BLOCK_SIZE;
-+ queued = queued + extra;
-+ }
-+
-+ /* XCBC continue: XOR previous result into 1st word */
-+ crypto_xor(req->cache, (const u8 *)req->state, AES_BLOCK_SIZE);
- }
-
-+ len = queued;
- /* Add a command descriptor for the cached data, if any */
- if (cache_len) {
- req->cache_dma = dma_map_single(priv->dev, req->cache,
-@@ -306,8 +403,9 @@ static int safexcel_ahash_send_req(struc
- req->cache_sz = cache_len;
- first_cdesc = safexcel_add_cdesc(priv, ring, 1,
- (cache_len == len),
-- req->cache_dma, cache_len, len,
-- ctx->base.ctxr_dma);
-+ req->cache_dma, cache_len,
-+ len, ctx->base.ctxr_dma,
-+ &dmmy);
- if (IS_ERR(first_cdesc)) {
- ret = PTR_ERR(first_cdesc);
- goto unmap_cache;
-@@ -319,10 +417,6 @@ static int safexcel_ahash_send_req(struc
- goto send_command;
- }
-
-- /* Skip descriptor generation for zero-length requests */
-- if (!areq->nbytes)
-- goto send_command;
--
- /* Now handle the current ahash request buffer(s) */
- req->nents = dma_map_sg(priv->dev, areq->src,
- sg_nents_for_len(areq->src,
-@@ -336,26 +430,34 @@ static int safexcel_ahash_send_req(struc
- for_each_sg(areq->src, sg, req->nents, i) {
- int sglen = sg_dma_len(sg);
-
-+ if (unlikely(sglen <= skip)) {
-+ skip -= sglen;
-+ continue;
-+ }
-+
- /* Do not overflow the request */
-- if (queued < sglen)
-+ if ((queued + skip) <= sglen)
- sglen = queued;
-+ else
-+ sglen -= skip;
-
- cdesc = safexcel_add_cdesc(priv, ring, !n_cdesc,
- !(queued - sglen),
-- sg_dma_address(sg),
-- sglen, len, ctx->base.ctxr_dma);
-+ sg_dma_address(sg) + skip, sglen,
-+ len, ctx->base.ctxr_dma, &dmmy);
- if (IS_ERR(cdesc)) {
- ret = PTR_ERR(cdesc);
- goto unmap_sg;
- }
-- n_cdesc++;
-
-- if (n_cdesc == 1)
-+ if (!n_cdesc)
- first_cdesc = cdesc;
-+ n_cdesc++;
-
- queued -= sglen;
- if (!queued)
- break;
-+ skip = 0;
- }
-
- send_command:
-@@ -363,9 +465,9 @@ send_command:
- safexcel_context_control(ctx, req, first_cdesc);
-
- /* Add the token */
-- safexcel_hash_token(first_cdesc, len, req->state_sz);
-+ safexcel_hash_token(first_cdesc, len, req->digest_sz, ctx->cbcmac);
-
-- req->result_dma = dma_map_single(priv->dev, req->state, req->state_sz,
-+ req->result_dma = dma_map_single(priv->dev, req->state, req->digest_sz,
- DMA_FROM_DEVICE);
- if (dma_mapping_error(priv->dev, req->result_dma)) {
- ret = -EINVAL;
-@@ -374,7 +476,7 @@ send_command:
-
- /* Add a result descriptor */
- rdesc = safexcel_add_rdesc(priv, ring, 1, 1, req->result_dma,
-- req->state_sz);
-+ req->digest_sz);
- if (IS_ERR(rdesc)) {
- ret = PTR_ERR(rdesc);
- goto unmap_result;
-@@ -382,17 +484,20 @@ send_command:
-
- safexcel_rdr_req_set(priv, ring, rdesc, &areq->base);
-
-- req->processed += len;
-+ req->processed += len - extra;
-
- *commands = n_cdesc;
- *results = 1;
- return 0;
-
- unmap_result:
-- dma_unmap_single(priv->dev, req->result_dma, req->state_sz,
-+ dma_unmap_single(priv->dev, req->result_dma, req->digest_sz,
- DMA_FROM_DEVICE);
- unmap_sg:
-- dma_unmap_sg(priv->dev, areq->src, req->nents, DMA_TO_DEVICE);
-+ if (req->nents) {
-+ dma_unmap_sg(priv->dev, areq->src, req->nents, DMA_TO_DEVICE);
-+ req->nents = 0;
-+ }
- cdesc_rollback:
- for (i = 0; i < n_cdesc; i++)
- safexcel_ring_rollback_wptr(priv, &priv->ring[ring].cdr);
-@@ -590,16 +695,12 @@ static int safexcel_ahash_enqueue(struct
-
- if (ctx->base.ctxr) {
- if (priv->flags & EIP197_TRC_CACHE && !ctx->base.needs_inv &&
-- req->processed &&
-- (/* invalidate for basic hash continuation finish */
-- (req->finish &&
-- (req->digest == CONTEXT_CONTROL_DIGEST_PRECOMPUTED)) ||
-+ /* invalidate for *any* non-XCBC continuation */
-+ ((req->not_first && !req->xcbcmac) ||
- /* invalidate if (i)digest changed */
- memcmp(ctx->base.ctxr->data, req->state, req->state_sz) ||
-- /* invalidate for HMAC continuation finish */
-- (req->finish && (req->processed != req->block_sz)) ||
- /* invalidate for HMAC finish with odigest changed */
-- (req->finish &&
-+ (req->finish && req->hmac &&
- memcmp(ctx->base.ctxr->data + (req->state_sz>>2),
- ctx->opad, req->state_sz))))
- /*
-@@ -622,6 +723,7 @@ static int safexcel_ahash_enqueue(struct
- if (!ctx->base.ctxr)
- return -ENOMEM;
- }
-+ req->not_first = true;
-
- ring = ctx->base.ring;
-
-@@ -691,8 +793,34 @@ static int safexcel_ahash_final(struct a
- else if (ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_SHA512)
- memcpy(areq->result, sha512_zero_message_hash,
- SHA512_DIGEST_SIZE);
-+ else if (ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_SM3) {
-+ memcpy(areq->result,
-+ EIP197_SM3_ZEROM_HASH, SM3_DIGEST_SIZE);
-+ }
-
- return 0;
-+ } else if (unlikely(req->digest == CONTEXT_CONTROL_DIGEST_XCM &&
-+ ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_MD5 &&
-+ req->len == sizeof(u32) && !areq->nbytes)) {
-+ /* Zero length CRC32 */
-+ memcpy(areq->result, ctx->ipad, sizeof(u32));
-+ return 0;
-+ } else if (unlikely(ctx->cbcmac && req->len == AES_BLOCK_SIZE &&
-+ !areq->nbytes)) {
-+ /* Zero length CBC MAC */
-+ memset(areq->result, 0, AES_BLOCK_SIZE);
-+ return 0;
-+ } else if (unlikely(req->xcbcmac && req->len == AES_BLOCK_SIZE &&
-+ !areq->nbytes)) {
-+ /* Zero length (X)CBC/CMAC */
-+ int i;
-+
-+ for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++)
-+ ((__be32 *)areq->result)[i] =
-+ cpu_to_be32(le32_to_cpu(ctx->ipad[i + 4]));//K3
-+ areq->result[0] ^= 0x80; // 10- padding
-+ crypto_cipher_encrypt_one(ctx->kaes, areq->result, areq->result);
-+ return 0;
- } else if (unlikely(req->hmac &&
- (req->len == req->block_sz) &&
- !areq->nbytes)) {
-@@ -792,6 +920,7 @@ static int safexcel_ahash_cra_init(struc
- ctx->priv = tmpl->priv;
- ctx->base.send = safexcel_ahash_send;
- ctx->base.handle_result = safexcel_handle_result;
-+ ctx->fb_do_setkey = false;
-
- crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
- sizeof(struct safexcel_ahash_req));
-@@ -808,6 +937,7 @@ static int safexcel_sha1_init(struct aha
- ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1;
- req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
- req->state_sz = SHA1_DIGEST_SIZE;
-+ req->digest_sz = SHA1_DIGEST_SIZE;
- req->block_sz = SHA1_BLOCK_SIZE;
-
- return 0;
-@@ -889,6 +1019,7 @@ static int safexcel_hmac_sha1_init(struc
- ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1;
- req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
- req->state_sz = SHA1_DIGEST_SIZE;
-+ req->digest_sz = SHA1_DIGEST_SIZE;
- req->block_sz = SHA1_BLOCK_SIZE;
- req->hmac = true;
-
-@@ -1125,6 +1256,7 @@ static int safexcel_sha256_init(struct a
- ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA256;
- req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
- req->state_sz = SHA256_DIGEST_SIZE;
-+ req->digest_sz = SHA256_DIGEST_SIZE;
- req->block_sz = SHA256_BLOCK_SIZE;
-
- return 0;
-@@ -1180,6 +1312,7 @@ static int safexcel_sha224_init(struct a
- ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA224;
- req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
- req->state_sz = SHA256_DIGEST_SIZE;
-+ req->digest_sz = SHA256_DIGEST_SIZE;
- req->block_sz = SHA256_BLOCK_SIZE;
-
- return 0;
-@@ -1248,6 +1381,7 @@ static int safexcel_hmac_sha224_init(str
- ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA224;
- req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
- req->state_sz = SHA256_DIGEST_SIZE;
-+ req->digest_sz = SHA256_DIGEST_SIZE;
- req->block_sz = SHA256_BLOCK_SIZE;
- req->hmac = true;
-
-@@ -1318,6 +1452,7 @@ static int safexcel_hmac_sha256_init(str
- ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA256;
- req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
- req->state_sz = SHA256_DIGEST_SIZE;
-+ req->digest_sz = SHA256_DIGEST_SIZE;
- req->block_sz = SHA256_BLOCK_SIZE;
- req->hmac = true;
-
-@@ -1375,6 +1510,7 @@ static int safexcel_sha512_init(struct a
- ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA512;
- req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
- req->state_sz = SHA512_DIGEST_SIZE;
-+ req->digest_sz = SHA512_DIGEST_SIZE;
- req->block_sz = SHA512_BLOCK_SIZE;
-
- return 0;
-@@ -1430,6 +1566,7 @@ static int safexcel_sha384_init(struct a
- ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA384;
- req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
- req->state_sz = SHA512_DIGEST_SIZE;
-+ req->digest_sz = SHA512_DIGEST_SIZE;
- req->block_sz = SHA512_BLOCK_SIZE;
-
- return 0;
-@@ -1498,6 +1635,7 @@ static int safexcel_hmac_sha512_init(str
- ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA512;
- req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
- req->state_sz = SHA512_DIGEST_SIZE;
-+ req->digest_sz = SHA512_DIGEST_SIZE;
- req->block_sz = SHA512_BLOCK_SIZE;
- req->hmac = true;
-
-@@ -1568,6 +1706,7 @@ static int safexcel_hmac_sha384_init(str
- ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA384;
- req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
- req->state_sz = SHA512_DIGEST_SIZE;
-+ req->digest_sz = SHA512_DIGEST_SIZE;
- req->block_sz = SHA512_BLOCK_SIZE;
- req->hmac = true;
-
-@@ -1625,6 +1764,7 @@ static int safexcel_md5_init(struct ahas
- ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_MD5;
- req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
- req->state_sz = MD5_DIGEST_SIZE;
-+ req->digest_sz = MD5_DIGEST_SIZE;
- req->block_sz = MD5_HMAC_BLOCK_SIZE;
-
- return 0;
-@@ -1686,6 +1826,7 @@ static int safexcel_hmac_md5_init(struct
- ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_MD5;
- req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
- req->state_sz = MD5_DIGEST_SIZE;
-+ req->digest_sz = MD5_DIGEST_SIZE;
- req->block_sz = MD5_HMAC_BLOCK_SIZE;
- req->len_is_le = true; /* MD5 is little endian! ... */
- req->hmac = true;
-@@ -1738,5 +1879,1235 @@ struct safexcel_alg_template safexcel_al
- .cra_module = THIS_MODULE,
- },
- },
-+ },
-+};
-+
-+static int safexcel_crc32_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm);
-+ int ret = safexcel_ahash_cra_init(tfm);
-+
-+ /* Default 'key' is all zeroes */
-+ memset(ctx->ipad, 0, sizeof(u32));
-+ return ret;
-+}
-+
-+static int safexcel_crc32_init(struct ahash_request *areq)
-+{
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
-+ struct safexcel_ahash_req *req = ahash_request_ctx(areq);
-+
-+ memset(req, 0, sizeof(*req));
-+
-+ /* Start from loaded key */
-+ req->state[0] = (__force __le32)le32_to_cpu(~ctx->ipad[0]);
-+ /* Set processed to non-zero to enable invalidation detection */
-+ req->len = sizeof(u32);
-+ req->processed = sizeof(u32);
-+
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_CRC32;
-+ req->digest = CONTEXT_CONTROL_DIGEST_XCM;
-+ req->state_sz = sizeof(u32);
-+ req->digest_sz = sizeof(u32);
-+ req->block_sz = sizeof(u32);
-+
-+ return 0;
-+}
-+
-+static int safexcel_crc32_setkey(struct crypto_ahash *tfm, const u8 *key,
-+ unsigned int keylen)
-+{
-+ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
-+
-+ if (keylen != sizeof(u32))
-+ return -EINVAL;
-+
-+ memcpy(ctx->ipad, key, sizeof(u32));
-+ return 0;
-+}
-+
-+static int safexcel_crc32_digest(struct ahash_request *areq)
-+{
-+ return safexcel_crc32_init(areq) ?: safexcel_ahash_finup(areq);
-+}
-+
-+struct safexcel_alg_template safexcel_alg_crc32 = {
-+ .type = SAFEXCEL_ALG_TYPE_AHASH,
-+ .algo_mask = 0,
-+ .alg.ahash = {
-+ .init = safexcel_crc32_init,
-+ .update = safexcel_ahash_update,
-+ .final = safexcel_ahash_final,
-+ .finup = safexcel_ahash_finup,
-+ .digest = safexcel_crc32_digest,
-+ .setkey = safexcel_crc32_setkey,
-+ .export = safexcel_ahash_export,
-+ .import = safexcel_ahash_import,
-+ .halg = {
-+ .digestsize = sizeof(u32),
-+ .statesize = sizeof(struct safexcel_ahash_export_state),
-+ .base = {
-+ .cra_name = "crc32",
-+ .cra_driver_name = "safexcel-crc32",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_OPTIONAL_KEY |
-+ CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
-+ .cra_init = safexcel_crc32_cra_init,
-+ .cra_exit = safexcel_ahash_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+ },
-+};
-+
-+static int safexcel_cbcmac_init(struct ahash_request *areq)
-+{
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
-+ struct safexcel_ahash_req *req = ahash_request_ctx(areq);
-+
-+ memset(req, 0, sizeof(*req));
-+
-+ /* Start from loaded keys */
-+ memcpy(req->state, ctx->ipad, ctx->key_sz);
-+ /* Set processed to non-zero to enable invalidation detection */
-+ req->len = AES_BLOCK_SIZE;
-+ req->processed = AES_BLOCK_SIZE;
-+
-+ req->digest = CONTEXT_CONTROL_DIGEST_XCM;
-+ req->state_sz = ctx->key_sz;
-+ req->digest_sz = AES_BLOCK_SIZE;
-+ req->block_sz = AES_BLOCK_SIZE;
-+ req->xcbcmac = true;
-+
-+ return 0;
-+}
-+
-+static int safexcel_cbcmac_setkey(struct crypto_ahash *tfm, const u8 *key,
-+ unsigned int len)
-+{
-+ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
-+ struct crypto_aes_ctx aes;
-+ int ret, i;
-+
-+ ret = aes_expandkey(&aes, key, len);
-+ if (ret)
-+ return ret;
-+
-+ memset(ctx->ipad, 0, 2 * AES_BLOCK_SIZE);
-+ for (i = 0; i < len / sizeof(u32); i++)
-+ ctx->ipad[i + 8] = (__force __le32)cpu_to_be32(aes.key_enc[i]);
-+
-+ if (len == AES_KEYSIZE_192) {
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC192;
-+ ctx->key_sz = AES_MAX_KEY_SIZE + 2 * AES_BLOCK_SIZE;
-+ } else if (len == AES_KEYSIZE_256) {
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC256;
-+ ctx->key_sz = AES_MAX_KEY_SIZE + 2 * AES_BLOCK_SIZE;
-+ } else {
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128;
-+ ctx->key_sz = AES_MIN_KEY_SIZE + 2 * AES_BLOCK_SIZE;
-+ }
-+ ctx->cbcmac = true;
-+
-+ memzero_explicit(&aes, sizeof(aes));
-+ return 0;
-+}
-+
-+static int safexcel_cbcmac_digest(struct ahash_request *areq)
-+{
-+ return safexcel_cbcmac_init(areq) ?: safexcel_ahash_finup(areq);
-+}
-+
-+struct safexcel_alg_template safexcel_alg_cbcmac = {
-+ .type = SAFEXCEL_ALG_TYPE_AHASH,
-+ .algo_mask = 0,
-+ .alg.ahash = {
-+ .init = safexcel_cbcmac_init,
-+ .update = safexcel_ahash_update,
-+ .final = safexcel_ahash_final,
-+ .finup = safexcel_ahash_finup,
-+ .digest = safexcel_cbcmac_digest,
-+ .setkey = safexcel_cbcmac_setkey,
-+ .export = safexcel_ahash_export,
-+ .import = safexcel_ahash_import,
-+ .halg = {
-+ .digestsize = AES_BLOCK_SIZE,
-+ .statesize = sizeof(struct safexcel_ahash_export_state),
-+ .base = {
-+ .cra_name = "cbcmac(aes)",
-+ .cra_driver_name = "safexcel-cbcmac-aes",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
-+ .cra_init = safexcel_ahash_cra_init,
-+ .cra_exit = safexcel_ahash_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+ },
-+};
-+
-+static int safexcel_xcbcmac_setkey(struct crypto_ahash *tfm, const u8 *key,
-+ unsigned int len)
-+{
-+ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
-+ struct crypto_aes_ctx aes;
-+ u32 key_tmp[3 * AES_BLOCK_SIZE / sizeof(u32)];
-+ int ret, i;
-+
-+ ret = aes_expandkey(&aes, key, len);
-+ if (ret)
-+ return ret;
-+
-+ /* precompute the XCBC key material */
-+ crypto_cipher_clear_flags(ctx->kaes, CRYPTO_TFM_REQ_MASK);
-+ crypto_cipher_set_flags(ctx->kaes, crypto_ahash_get_flags(tfm) &
-+ CRYPTO_TFM_REQ_MASK);
-+ ret = crypto_cipher_setkey(ctx->kaes, key, len);
-+ if (ret)
-+ return ret;
-+
-+ crypto_cipher_encrypt_one(ctx->kaes, (u8 *)key_tmp + 2 * AES_BLOCK_SIZE,
-+ "\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1");
-+ crypto_cipher_encrypt_one(ctx->kaes, (u8 *)key_tmp,
-+ "\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2");
-+ crypto_cipher_encrypt_one(ctx->kaes, (u8 *)key_tmp + AES_BLOCK_SIZE,
-+ "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3");
-+ for (i = 0; i < 3 * AES_BLOCK_SIZE / sizeof(u32); i++)
-+ ctx->ipad[i] =
-+ cpu_to_le32((__force u32)cpu_to_be32(key_tmp[i]));
-+
-+ crypto_cipher_clear_flags(ctx->kaes, CRYPTO_TFM_REQ_MASK);
-+ crypto_cipher_set_flags(ctx->kaes, crypto_ahash_get_flags(tfm) &
-+ CRYPTO_TFM_REQ_MASK);
-+ ret = crypto_cipher_setkey(ctx->kaes,
-+ (u8 *)key_tmp + 2 * AES_BLOCK_SIZE,
-+ AES_MIN_KEY_SIZE);
-+ if (ret)
-+ return ret;
-+
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128;
-+ ctx->key_sz = AES_MIN_KEY_SIZE + 2 * AES_BLOCK_SIZE;
-+ ctx->cbcmac = false;
-+
-+ memzero_explicit(&aes, sizeof(aes));
-+ return 0;
-+}
-+
-+static int safexcel_xcbcmac_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_ahash_cra_init(tfm);
-+ ctx->kaes = crypto_alloc_cipher("aes", 0, 0);
-+ return PTR_ERR_OR_ZERO(ctx->kaes);
-+}
-+
-+static void safexcel_xcbcmac_cra_exit(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ crypto_free_cipher(ctx->kaes);
-+ safexcel_ahash_cra_exit(tfm);
-+}
-+
-+struct safexcel_alg_template safexcel_alg_xcbcmac = {
-+ .type = SAFEXCEL_ALG_TYPE_AHASH,
-+ .algo_mask = 0,
-+ .alg.ahash = {
-+ .init = safexcel_cbcmac_init,
-+ .update = safexcel_ahash_update,
-+ .final = safexcel_ahash_final,
-+ .finup = safexcel_ahash_finup,
-+ .digest = safexcel_cbcmac_digest,
-+ .setkey = safexcel_xcbcmac_setkey,
-+ .export = safexcel_ahash_export,
-+ .import = safexcel_ahash_import,
-+ .halg = {
-+ .digestsize = AES_BLOCK_SIZE,
-+ .statesize = sizeof(struct safexcel_ahash_export_state),
-+ .base = {
-+ .cra_name = "xcbc(aes)",
-+ .cra_driver_name = "safexcel-xcbc-aes",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = AES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
-+ .cra_init = safexcel_xcbcmac_cra_init,
-+ .cra_exit = safexcel_xcbcmac_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+ },
-+};
-+
-+static int safexcel_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,
-+ unsigned int len)
-+{
-+ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
-+ struct crypto_aes_ctx aes;
-+ __be64 consts[4];
-+ u64 _const[2];
-+ u8 msb_mask, gfmask;
-+ int ret, i;
-+
-+ ret = aes_expandkey(&aes, key, len);
-+ if (ret)
-+ return ret;
-+
-+ for (i = 0; i < len / sizeof(u32); i++)
-+ ctx->ipad[i + 8] =
-+ cpu_to_le32((__force u32)cpu_to_be32(aes.key_enc[i]));
-+
-+ /* precompute the CMAC key material */
-+ crypto_cipher_clear_flags(ctx->kaes, CRYPTO_TFM_REQ_MASK);
-+ crypto_cipher_set_flags(ctx->kaes, crypto_ahash_get_flags(tfm) &
-+ CRYPTO_TFM_REQ_MASK);
-+ ret = crypto_cipher_setkey(ctx->kaes, key, len);
-+ if (ret)
-+ return ret;
-+
-+ /* code below borrowed from crypto/cmac.c */
-+ /* encrypt the zero block */
-+ memset(consts, 0, AES_BLOCK_SIZE);
-+ crypto_cipher_encrypt_one(ctx->kaes, (u8 *)consts, (u8 *)consts);
-+
-+ gfmask = 0x87;
-+ _const[0] = be64_to_cpu(consts[1]);
-+ _const[1] = be64_to_cpu(consts[0]);
-+
-+ /* gf(2^128) multiply zero-ciphertext with u and u^2 */
-+ for (i = 0; i < 4; i += 2) {
-+ msb_mask = ((s64)_const[1] >> 63) & gfmask;
-+ _const[1] = (_const[1] << 1) | (_const[0] >> 63);
-+ _const[0] = (_const[0] << 1) ^ msb_mask;
-+
-+ consts[i + 0] = cpu_to_be64(_const[1]);
-+ consts[i + 1] = cpu_to_be64(_const[0]);
-+ }
-+ /* end of code borrowed from crypto/cmac.c */
-+
-+ for (i = 0; i < 2 * AES_BLOCK_SIZE / sizeof(u32); i++)
-+ ctx->ipad[i] = (__force __le32)cpu_to_be32(((u32 *)consts)[i]);
-+
-+ if (len == AES_KEYSIZE_192) {
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC192;
-+ ctx->key_sz = AES_MAX_KEY_SIZE + 2 * AES_BLOCK_SIZE;
-+ } else if (len == AES_KEYSIZE_256) {
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC256;
-+ ctx->key_sz = AES_MAX_KEY_SIZE + 2 * AES_BLOCK_SIZE;
-+ } else {
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128;
-+ ctx->key_sz = AES_MIN_KEY_SIZE + 2 * AES_BLOCK_SIZE;
-+ }
-+ ctx->cbcmac = false;
-+
-+ memzero_explicit(&aes, sizeof(aes));
-+ return 0;
-+}
-+
-+struct safexcel_alg_template safexcel_alg_cmac = {
-+ .type = SAFEXCEL_ALG_TYPE_AHASH,
-+ .algo_mask = 0,
-+ .alg.ahash = {
-+ .init = safexcel_cbcmac_init,
-+ .update = safexcel_ahash_update,
-+ .final = safexcel_ahash_final,
-+ .finup = safexcel_ahash_finup,
-+ .digest = safexcel_cbcmac_digest,
-+ .setkey = safexcel_cmac_setkey,
-+ .export = safexcel_ahash_export,
-+ .import = safexcel_ahash_import,
-+ .halg = {
-+ .digestsize = AES_BLOCK_SIZE,
-+ .statesize = sizeof(struct safexcel_ahash_export_state),
-+ .base = {
-+ .cra_name = "cmac(aes)",
-+ .cra_driver_name = "safexcel-cmac-aes",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = AES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
-+ .cra_init = safexcel_xcbcmac_cra_init,
-+ .cra_exit = safexcel_xcbcmac_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+ },
-+};
-+
-+static int safexcel_sm3_init(struct ahash_request *areq)
-+{
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
-+ struct safexcel_ahash_req *req = ahash_request_ctx(areq);
-+
-+ memset(req, 0, sizeof(*req));
-+
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SM3;
-+ req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
-+ req->state_sz = SM3_DIGEST_SIZE;
-+ req->digest_sz = SM3_DIGEST_SIZE;
-+ req->block_sz = SM3_BLOCK_SIZE;
-+
-+ return 0;
-+}
-+
-+static int safexcel_sm3_digest(struct ahash_request *areq)
-+{
-+ int ret = safexcel_sm3_init(areq);
-+
-+ if (ret)
-+ return ret;
-+
-+ return safexcel_ahash_finup(areq);
-+}
-+
-+struct safexcel_alg_template safexcel_alg_sm3 = {
-+ .type = SAFEXCEL_ALG_TYPE_AHASH,
-+ .algo_mask = SAFEXCEL_ALG_SM3,
-+ .alg.ahash = {
-+ .init = safexcel_sm3_init,
-+ .update = safexcel_ahash_update,
-+ .final = safexcel_ahash_final,
-+ .finup = safexcel_ahash_finup,
-+ .digest = safexcel_sm3_digest,
-+ .export = safexcel_ahash_export,
-+ .import = safexcel_ahash_import,
-+ .halg = {
-+ .digestsize = SM3_DIGEST_SIZE,
-+ .statesize = sizeof(struct safexcel_ahash_export_state),
-+ .base = {
-+ .cra_name = "sm3",
-+ .cra_driver_name = "safexcel-sm3",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = SM3_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
-+ .cra_init = safexcel_ahash_cra_init,
-+ .cra_exit = safexcel_ahash_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+ },
-+};
-+
-+static int safexcel_hmac_sm3_setkey(struct crypto_ahash *tfm, const u8 *key,
-+ unsigned int keylen)
-+{
-+ return safexcel_hmac_alg_setkey(tfm, key, keylen, "safexcel-sm3",
-+ SM3_DIGEST_SIZE);
-+}
-+
-+static int safexcel_hmac_sm3_init(struct ahash_request *areq)
-+{
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
-+ struct safexcel_ahash_req *req = ahash_request_ctx(areq);
-+
-+ memset(req, 0, sizeof(*req));
-+
-+ /* Start from ipad precompute */
-+ memcpy(req->state, ctx->ipad, SM3_DIGEST_SIZE);
-+ /* Already processed the key^ipad part now! */
-+ req->len = SM3_BLOCK_SIZE;
-+ req->processed = SM3_BLOCK_SIZE;
-+
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SM3;
-+ req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
-+ req->state_sz = SM3_DIGEST_SIZE;
-+ req->digest_sz = SM3_DIGEST_SIZE;
-+ req->block_sz = SM3_BLOCK_SIZE;
-+ req->hmac = true;
-+
-+ return 0;
-+}
-+
-+static int safexcel_hmac_sm3_digest(struct ahash_request *areq)
-+{
-+ int ret = safexcel_hmac_sm3_init(areq);
-+
-+ if (ret)
-+ return ret;
-+
-+ return safexcel_ahash_finup(areq);
-+}
-+
-+struct safexcel_alg_template safexcel_alg_hmac_sm3 = {
-+ .type = SAFEXCEL_ALG_TYPE_AHASH,
-+ .algo_mask = SAFEXCEL_ALG_SM3,
-+ .alg.ahash = {
-+ .init = safexcel_hmac_sm3_init,
-+ .update = safexcel_ahash_update,
-+ .final = safexcel_ahash_final,
-+ .finup = safexcel_ahash_finup,
-+ .digest = safexcel_hmac_sm3_digest,
-+ .setkey = safexcel_hmac_sm3_setkey,
-+ .export = safexcel_ahash_export,
-+ .import = safexcel_ahash_import,
-+ .halg = {
-+ .digestsize = SM3_DIGEST_SIZE,
-+ .statesize = sizeof(struct safexcel_ahash_export_state),
-+ .base = {
-+ .cra_name = "hmac(sm3)",
-+ .cra_driver_name = "safexcel-hmac-sm3",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = SM3_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
-+ .cra_init = safexcel_ahash_cra_init,
-+ .cra_exit = safexcel_ahash_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+ },
-+};
-+
-+static int safexcel_sha3_224_init(struct ahash_request *areq)
-+{
-+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
-+ struct safexcel_ahash_req *req = ahash_request_ctx(areq);
-+
-+ memset(req, 0, sizeof(*req));
-+
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA3_224;
-+ req->digest = CONTEXT_CONTROL_DIGEST_INITIAL;
-+ req->state_sz = SHA3_224_DIGEST_SIZE;
-+ req->digest_sz = SHA3_224_DIGEST_SIZE;
-+ req->block_sz = SHA3_224_BLOCK_SIZE;
-+ ctx->do_fallback = false;
-+ ctx->fb_init_done = false;
-+ return 0;
-+}
-+
-+static int safexcel_sha3_fbcheck(struct ahash_request *req)
-+{
-+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
-+ struct ahash_request *subreq = ahash_request_ctx(req);
-+ int ret = 0;
-+
-+ if (ctx->do_fallback) {
-+ ahash_request_set_tfm(subreq, ctx->fback);
-+ ahash_request_set_callback(subreq, req->base.flags,
-+ req->base.complete, req->base.data);
-+ ahash_request_set_crypt(subreq, req->src, req->result,
-+ req->nbytes);
-+ if (!ctx->fb_init_done) {
-+ if (ctx->fb_do_setkey) {
-+ /* Set fallback cipher HMAC key */
-+ u8 key[SHA3_224_BLOCK_SIZE];
-+
-+ memcpy(key, ctx->ipad,
-+ crypto_ahash_blocksize(ctx->fback) / 2);
-+ memcpy(key +
-+ crypto_ahash_blocksize(ctx->fback) / 2,
-+ ctx->opad,
-+ crypto_ahash_blocksize(ctx->fback) / 2);
-+ ret = crypto_ahash_setkey(ctx->fback, key,
-+ crypto_ahash_blocksize(ctx->fback));
-+ memzero_explicit(key,
-+ crypto_ahash_blocksize(ctx->fback));
-+ ctx->fb_do_setkey = false;
-+ }
-+ ret = ret ?: crypto_ahash_init(subreq);
-+ ctx->fb_init_done = true;
-+ }
-+ }
-+ return ret;
-+}
-+
-+static int safexcel_sha3_update(struct ahash_request *req)
-+{
-+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
-+ struct ahash_request *subreq = ahash_request_ctx(req);
-+
-+ ctx->do_fallback = true;
-+ return safexcel_sha3_fbcheck(req) ?: crypto_ahash_update(subreq);
-+}
-+
-+static int safexcel_sha3_final(struct ahash_request *req)
-+{
-+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
-+ struct ahash_request *subreq = ahash_request_ctx(req);
-+
-+ ctx->do_fallback = true;
-+ return safexcel_sha3_fbcheck(req) ?: crypto_ahash_final(subreq);
-+}
-+
-+static int safexcel_sha3_finup(struct ahash_request *req)
-+{
-+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
-+ struct ahash_request *subreq = ahash_request_ctx(req);
-+
-+ ctx->do_fallback |= !req->nbytes;
-+ if (ctx->do_fallback)
-+ /* Update or ex/import happened or len 0, cannot use the HW */
-+ return safexcel_sha3_fbcheck(req) ?:
-+ crypto_ahash_finup(subreq);
-+ else
-+ return safexcel_ahash_finup(req);
-+}
-+
-+static int safexcel_sha3_digest_fallback(struct ahash_request *req)
-+{
-+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
-+ struct ahash_request *subreq = ahash_request_ctx(req);
-+
-+ ctx->do_fallback = true;
-+ ctx->fb_init_done = false;
-+ return safexcel_sha3_fbcheck(req) ?: crypto_ahash_finup(subreq);
-+}
-+
-+static int safexcel_sha3_224_digest(struct ahash_request *req)
-+{
-+ if (req->nbytes)
-+ return safexcel_sha3_224_init(req) ?: safexcel_ahash_finup(req);
-+
-+ /* HW cannot do zero length hash, use fallback instead */
-+ return safexcel_sha3_digest_fallback(req);
-+}
-+
-+static int safexcel_sha3_export(struct ahash_request *req, void *out)
-+{
-+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
-+ struct ahash_request *subreq = ahash_request_ctx(req);
-+
-+ ctx->do_fallback = true;
-+ return safexcel_sha3_fbcheck(req) ?: crypto_ahash_export(subreq, out);
-+}
-+
-+static int safexcel_sha3_import(struct ahash_request *req, const void *in)
-+{
-+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
-+ struct ahash_request *subreq = ahash_request_ctx(req);
-+
-+ ctx->do_fallback = true;
-+ return safexcel_sha3_fbcheck(req) ?: crypto_ahash_import(subreq, in);
-+ // return safexcel_ahash_import(req, in);
-+}
-+
-+static int safexcel_sha3_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct crypto_ahash *ahash = __crypto_ahash_cast(tfm);
-+ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ safexcel_ahash_cra_init(tfm);
-+
-+ /* Allocate fallback implementation */
-+ ctx->fback = crypto_alloc_ahash(crypto_tfm_alg_name(tfm), 0,
-+ CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_NEED_FALLBACK);
-+ if (IS_ERR(ctx->fback))
-+ return PTR_ERR(ctx->fback);
-+
-+ /* Update statesize from fallback algorithm! */
-+ crypto_hash_alg_common(ahash)->statesize =
-+ crypto_ahash_statesize(ctx->fback);
-+ crypto_ahash_set_reqsize(ahash, max(sizeof(struct safexcel_ahash_req),
-+ sizeof(struct ahash_request) +
-+ crypto_ahash_reqsize(ctx->fback)));
-+ return 0;
-+}
-+
-+static void safexcel_sha3_cra_exit(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ crypto_free_ahash(ctx->fback);
-+ safexcel_ahash_cra_exit(tfm);
-+}
-+
-+struct safexcel_alg_template safexcel_alg_sha3_224 = {
-+ .type = SAFEXCEL_ALG_TYPE_AHASH,
-+ .algo_mask = SAFEXCEL_ALG_SHA3,
-+ .alg.ahash = {
-+ .init = safexcel_sha3_224_init,
-+ .update = safexcel_sha3_update,
-+ .final = safexcel_sha3_final,
-+ .finup = safexcel_sha3_finup,
-+ .digest = safexcel_sha3_224_digest,
-+ .export = safexcel_sha3_export,
-+ .import = safexcel_sha3_import,
-+ .halg = {
-+ .digestsize = SHA3_224_DIGEST_SIZE,
-+ .statesize = sizeof(struct safexcel_ahash_export_state),
-+ .base = {
-+ .cra_name = "sha3-224",
-+ .cra_driver_name = "safexcel-sha3-224",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY |
-+ CRYPTO_ALG_NEED_FALLBACK,
-+ .cra_blocksize = SHA3_224_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
-+ .cra_init = safexcel_sha3_cra_init,
-+ .cra_exit = safexcel_sha3_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+ },
-+};
-+
-+static int safexcel_sha3_256_init(struct ahash_request *areq)
-+{
-+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
-+ struct safexcel_ahash_req *req = ahash_request_ctx(areq);
-+
-+ memset(req, 0, sizeof(*req));
-+
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA3_256;
-+ req->digest = CONTEXT_CONTROL_DIGEST_INITIAL;
-+ req->state_sz = SHA3_256_DIGEST_SIZE;
-+ req->digest_sz = SHA3_256_DIGEST_SIZE;
-+ req->block_sz = SHA3_256_BLOCK_SIZE;
-+ ctx->do_fallback = false;
-+ ctx->fb_init_done = false;
-+ return 0;
-+}
-+
-+static int safexcel_sha3_256_digest(struct ahash_request *req)
-+{
-+ if (req->nbytes)
-+ return safexcel_sha3_256_init(req) ?: safexcel_ahash_finup(req);
-+
-+ /* HW cannot do zero length hash, use fallback instead */
-+ return safexcel_sha3_digest_fallback(req);
-+}
-+
-+struct safexcel_alg_template safexcel_alg_sha3_256 = {
-+ .type = SAFEXCEL_ALG_TYPE_AHASH,
-+ .algo_mask = SAFEXCEL_ALG_SHA3,
-+ .alg.ahash = {
-+ .init = safexcel_sha3_256_init,
-+ .update = safexcel_sha3_update,
-+ .final = safexcel_sha3_final,
-+ .finup = safexcel_sha3_finup,
-+ .digest = safexcel_sha3_256_digest,
-+ .export = safexcel_sha3_export,
-+ .import = safexcel_sha3_import,
-+ .halg = {
-+ .digestsize = SHA3_256_DIGEST_SIZE,
-+ .statesize = sizeof(struct safexcel_ahash_export_state),
-+ .base = {
-+ .cra_name = "sha3-256",
-+ .cra_driver_name = "safexcel-sha3-256",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY |
-+ CRYPTO_ALG_NEED_FALLBACK,
-+ .cra_blocksize = SHA3_256_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
-+ .cra_init = safexcel_sha3_cra_init,
-+ .cra_exit = safexcel_sha3_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+ },
-+};
-+
-+static int safexcel_sha3_384_init(struct ahash_request *areq)
-+{
-+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
-+ struct safexcel_ahash_req *req = ahash_request_ctx(areq);
-+
-+ memset(req, 0, sizeof(*req));
-+
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA3_384;
-+ req->digest = CONTEXT_CONTROL_DIGEST_INITIAL;
-+ req->state_sz = SHA3_384_DIGEST_SIZE;
-+ req->digest_sz = SHA3_384_DIGEST_SIZE;
-+ req->block_sz = SHA3_384_BLOCK_SIZE;
-+ ctx->do_fallback = false;
-+ ctx->fb_init_done = false;
-+ return 0;
-+}
-+
-+static int safexcel_sha3_384_digest(struct ahash_request *req)
-+{
-+ if (req->nbytes)
-+ return safexcel_sha3_384_init(req) ?: safexcel_ahash_finup(req);
-+
-+ /* HW cannot do zero length hash, use fallback instead */
-+ return safexcel_sha3_digest_fallback(req);
-+}
-+
-+struct safexcel_alg_template safexcel_alg_sha3_384 = {
-+ .type = SAFEXCEL_ALG_TYPE_AHASH,
-+ .algo_mask = SAFEXCEL_ALG_SHA3,
-+ .alg.ahash = {
-+ .init = safexcel_sha3_384_init,
-+ .update = safexcel_sha3_update,
-+ .final = safexcel_sha3_final,
-+ .finup = safexcel_sha3_finup,
-+ .digest = safexcel_sha3_384_digest,
-+ .export = safexcel_sha3_export,
-+ .import = safexcel_sha3_import,
-+ .halg = {
-+ .digestsize = SHA3_384_DIGEST_SIZE,
-+ .statesize = sizeof(struct safexcel_ahash_export_state),
-+ .base = {
-+ .cra_name = "sha3-384",
-+ .cra_driver_name = "safexcel-sha3-384",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY |
-+ CRYPTO_ALG_NEED_FALLBACK,
-+ .cra_blocksize = SHA3_384_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
-+ .cra_init = safexcel_sha3_cra_init,
-+ .cra_exit = safexcel_sha3_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+ },
-+};
-+
-+static int safexcel_sha3_512_init(struct ahash_request *areq)
-+{
-+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
-+ struct safexcel_ahash_req *req = ahash_request_ctx(areq);
-+
-+ memset(req, 0, sizeof(*req));
-+
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA3_512;
-+ req->digest = CONTEXT_CONTROL_DIGEST_INITIAL;
-+ req->state_sz = SHA3_512_DIGEST_SIZE;
-+ req->digest_sz = SHA3_512_DIGEST_SIZE;
-+ req->block_sz = SHA3_512_BLOCK_SIZE;
-+ ctx->do_fallback = false;
-+ ctx->fb_init_done = false;
-+ return 0;
-+}
-+
-+static int safexcel_sha3_512_digest(struct ahash_request *req)
-+{
-+ if (req->nbytes)
-+ return safexcel_sha3_512_init(req) ?: safexcel_ahash_finup(req);
-+
-+ /* HW cannot do zero length hash, use fallback instead */
-+ return safexcel_sha3_digest_fallback(req);
-+}
-+
-+struct safexcel_alg_template safexcel_alg_sha3_512 = {
-+ .type = SAFEXCEL_ALG_TYPE_AHASH,
-+ .algo_mask = SAFEXCEL_ALG_SHA3,
-+ .alg.ahash = {
-+ .init = safexcel_sha3_512_init,
-+ .update = safexcel_sha3_update,
-+ .final = safexcel_sha3_final,
-+ .finup = safexcel_sha3_finup,
-+ .digest = safexcel_sha3_512_digest,
-+ .export = safexcel_sha3_export,
-+ .import = safexcel_sha3_import,
-+ .halg = {
-+ .digestsize = SHA3_512_DIGEST_SIZE,
-+ .statesize = sizeof(struct safexcel_ahash_export_state),
-+ .base = {
-+ .cra_name = "sha3-512",
-+ .cra_driver_name = "safexcel-sha3-512",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY |
-+ CRYPTO_ALG_NEED_FALLBACK,
-+ .cra_blocksize = SHA3_512_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
-+ .cra_init = safexcel_sha3_cra_init,
-+ .cra_exit = safexcel_sha3_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+ },
-+};
-+
-+static int safexcel_hmac_sha3_cra_init(struct crypto_tfm *tfm, const char *alg)
-+{
-+ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm);
-+ int ret;
-+
-+ ret = safexcel_sha3_cra_init(tfm);
-+ if (ret)
-+ return ret;
-+
-+ /* Allocate precalc basic digest implementation */
-+ ctx->shpre = crypto_alloc_shash(alg, 0, CRYPTO_ALG_NEED_FALLBACK);
-+ if (IS_ERR(ctx->shpre))
-+ return PTR_ERR(ctx->shpre);
-+
-+ ctx->shdesc = kmalloc(sizeof(*ctx->shdesc) +
-+ crypto_shash_descsize(ctx->shpre), GFP_KERNEL);
-+ if (!ctx->shdesc) {
-+ crypto_free_shash(ctx->shpre);
-+ return -ENOMEM;
-+ }
-+ ctx->shdesc->tfm = ctx->shpre;
-+ return 0;
-+}
-+
-+static void safexcel_hmac_sha3_cra_exit(struct crypto_tfm *tfm)
-+{
-+ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ crypto_free_ahash(ctx->fback);
-+ crypto_free_shash(ctx->shpre);
-+ kfree(ctx->shdesc);
-+ safexcel_ahash_cra_exit(tfm);
-+}
-+
-+static int safexcel_hmac_sha3_setkey(struct crypto_ahash *tfm, const u8 *key,
-+ unsigned int keylen)
-+{
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
-+ int ret = 0;
-+
-+ if (keylen > crypto_ahash_blocksize(tfm)) {
-+ /*
-+ * If the key is larger than the blocksize, then hash it
-+ * first using our fallback cipher
-+ */
-+ ret = crypto_shash_digest(ctx->shdesc, key, keylen,
-+ (u8 *)ctx->ipad);
-+ keylen = crypto_shash_digestsize(ctx->shpre);
-+
-+ /*
-+ * If the digest is larger than half the blocksize, we need to
-+ * move the rest to opad due to the way our HMAC infra works.
-+ */
-+ if (keylen > crypto_ahash_blocksize(tfm) / 2)
-+ /* Buffers overlap, need to use memmove iso memcpy! */
-+ memmove(ctx->opad,
-+ (u8 *)ctx->ipad +
-+ crypto_ahash_blocksize(tfm) / 2,
-+ keylen - crypto_ahash_blocksize(tfm) / 2);
-+ } else {
-+ /*
-+ * Copy the key to our ipad & opad buffers
-+ * Note that ipad and opad each contain one half of the key,
-+ * to match the existing HMAC driver infrastructure.
-+ */
-+ if (keylen <= crypto_ahash_blocksize(tfm) / 2) {
-+ memcpy(ctx->ipad, key, keylen);
-+ } else {
-+ memcpy(ctx->ipad, key,
-+ crypto_ahash_blocksize(tfm) / 2);
-+ memcpy(ctx->opad,
-+ key + crypto_ahash_blocksize(tfm) / 2,
-+ keylen - crypto_ahash_blocksize(tfm) / 2);
-+ }
-+ }
-+
-+ /* Pad key with zeroes */
-+ if (keylen <= crypto_ahash_blocksize(tfm) / 2) {
-+ memset((u8 *)ctx->ipad + keylen, 0,
-+ crypto_ahash_blocksize(tfm) / 2 - keylen);
-+ memset(ctx->opad, 0, crypto_ahash_blocksize(tfm) / 2);
-+ } else {
-+ memset((u8 *)ctx->opad + keylen -
-+ crypto_ahash_blocksize(tfm) / 2, 0,
-+ crypto_ahash_blocksize(tfm) - keylen);
-+ }
-+
-+ /* If doing fallback, still need to set the new key! */
-+ ctx->fb_do_setkey = true;
-+ return ret;
-+}
-+
-+static int safexcel_hmac_sha3_224_init(struct ahash_request *areq)
-+{
-+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
-+ struct safexcel_ahash_req *req = ahash_request_ctx(areq);
-+
-+ memset(req, 0, sizeof(*req));
-+
-+ /* Copy (half of) the key */
-+ memcpy(req->state, ctx->ipad, SHA3_224_BLOCK_SIZE / 2);
-+ /* Start of HMAC should have len == processed == blocksize */
-+ req->len = SHA3_224_BLOCK_SIZE;
-+ req->processed = SHA3_224_BLOCK_SIZE;
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA3_224;
-+ req->digest = CONTEXT_CONTROL_DIGEST_HMAC;
-+ req->state_sz = SHA3_224_BLOCK_SIZE / 2;
-+ req->digest_sz = SHA3_224_DIGEST_SIZE;
-+ req->block_sz = SHA3_224_BLOCK_SIZE;
-+ req->hmac = true;
-+ ctx->do_fallback = false;
-+ ctx->fb_init_done = false;
-+ return 0;
-+}
-+
-+static int safexcel_hmac_sha3_224_digest(struct ahash_request *req)
-+{
-+ if (req->nbytes)
-+ return safexcel_hmac_sha3_224_init(req) ?:
-+ safexcel_ahash_finup(req);
-+
-+ /* HW cannot do zero length HMAC, use fallback instead */
-+ return safexcel_sha3_digest_fallback(req);
-+}
-+
-+static int safexcel_hmac_sha3_224_cra_init(struct crypto_tfm *tfm)
-+{
-+ return safexcel_hmac_sha3_cra_init(tfm, "sha3-224");
-+}
-+
-+struct safexcel_alg_template safexcel_alg_hmac_sha3_224 = {
-+ .type = SAFEXCEL_ALG_TYPE_AHASH,
-+ .algo_mask = SAFEXCEL_ALG_SHA3,
-+ .alg.ahash = {
-+ .init = safexcel_hmac_sha3_224_init,
-+ .update = safexcel_sha3_update,
-+ .final = safexcel_sha3_final,
-+ .finup = safexcel_sha3_finup,
-+ .digest = safexcel_hmac_sha3_224_digest,
-+ .setkey = safexcel_hmac_sha3_setkey,
-+ .export = safexcel_sha3_export,
-+ .import = safexcel_sha3_import,
-+ .halg = {
-+ .digestsize = SHA3_224_DIGEST_SIZE,
-+ .statesize = sizeof(struct safexcel_ahash_export_state),
-+ .base = {
-+ .cra_name = "hmac(sha3-224)",
-+ .cra_driver_name = "safexcel-hmac-sha3-224",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY |
-+ CRYPTO_ALG_NEED_FALLBACK,
-+ .cra_blocksize = SHA3_224_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
-+ .cra_init = safexcel_hmac_sha3_224_cra_init,
-+ .cra_exit = safexcel_hmac_sha3_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+ },
-+};
-+
-+static int safexcel_hmac_sha3_256_init(struct ahash_request *areq)
-+{
-+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
-+ struct safexcel_ahash_req *req = ahash_request_ctx(areq);
-+
-+ memset(req, 0, sizeof(*req));
-+
-+ /* Copy (half of) the key */
-+ memcpy(req->state, ctx->ipad, SHA3_256_BLOCK_SIZE / 2);
-+ /* Start of HMAC should have len == processed == blocksize */
-+ req->len = SHA3_256_BLOCK_SIZE;
-+ req->processed = SHA3_256_BLOCK_SIZE;
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA3_256;
-+ req->digest = CONTEXT_CONTROL_DIGEST_HMAC;
-+ req->state_sz = SHA3_256_BLOCK_SIZE / 2;
-+ req->digest_sz = SHA3_256_DIGEST_SIZE;
-+ req->block_sz = SHA3_256_BLOCK_SIZE;
-+ req->hmac = true;
-+ ctx->do_fallback = false;
-+ ctx->fb_init_done = false;
-+ return 0;
-+}
-+
-+static int safexcel_hmac_sha3_256_digest(struct ahash_request *req)
-+{
-+ if (req->nbytes)
-+ return safexcel_hmac_sha3_256_init(req) ?:
-+ safexcel_ahash_finup(req);
-+
-+ /* HW cannot do zero length HMAC, use fallback instead */
-+ return safexcel_sha3_digest_fallback(req);
-+}
-+
-+static int safexcel_hmac_sha3_256_cra_init(struct crypto_tfm *tfm)
-+{
-+ return safexcel_hmac_sha3_cra_init(tfm, "sha3-256");
-+}
-+
-+struct safexcel_alg_template safexcel_alg_hmac_sha3_256 = {
-+ .type = SAFEXCEL_ALG_TYPE_AHASH,
-+ .algo_mask = SAFEXCEL_ALG_SHA3,
-+ .alg.ahash = {
-+ .init = safexcel_hmac_sha3_256_init,
-+ .update = safexcel_sha3_update,
-+ .final = safexcel_sha3_final,
-+ .finup = safexcel_sha3_finup,
-+ .digest = safexcel_hmac_sha3_256_digest,
-+ .setkey = safexcel_hmac_sha3_setkey,
-+ .export = safexcel_sha3_export,
-+ .import = safexcel_sha3_import,
-+ .halg = {
-+ .digestsize = SHA3_256_DIGEST_SIZE,
-+ .statesize = sizeof(struct safexcel_ahash_export_state),
-+ .base = {
-+ .cra_name = "hmac(sha3-256)",
-+ .cra_driver_name = "safexcel-hmac-sha3-256",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY |
-+ CRYPTO_ALG_NEED_FALLBACK,
-+ .cra_blocksize = SHA3_256_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
-+ .cra_init = safexcel_hmac_sha3_256_cra_init,
-+ .cra_exit = safexcel_hmac_sha3_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+ },
-+};
-+
-+static int safexcel_hmac_sha3_384_init(struct ahash_request *areq)
-+{
-+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
-+ struct safexcel_ahash_req *req = ahash_request_ctx(areq);
-+
-+ memset(req, 0, sizeof(*req));
-+
-+ /* Copy (half of) the key */
-+ memcpy(req->state, ctx->ipad, SHA3_384_BLOCK_SIZE / 2);
-+ /* Start of HMAC should have len == processed == blocksize */
-+ req->len = SHA3_384_BLOCK_SIZE;
-+ req->processed = SHA3_384_BLOCK_SIZE;
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA3_384;
-+ req->digest = CONTEXT_CONTROL_DIGEST_HMAC;
-+ req->state_sz = SHA3_384_BLOCK_SIZE / 2;
-+ req->digest_sz = SHA3_384_DIGEST_SIZE;
-+ req->block_sz = SHA3_384_BLOCK_SIZE;
-+ req->hmac = true;
-+ ctx->do_fallback = false;
-+ ctx->fb_init_done = false;
-+ return 0;
-+}
-+
-+static int safexcel_hmac_sha3_384_digest(struct ahash_request *req)
-+{
-+ if (req->nbytes)
-+ return safexcel_hmac_sha3_384_init(req) ?:
-+ safexcel_ahash_finup(req);
-+
-+ /* HW cannot do zero length HMAC, use fallback instead */
-+ return safexcel_sha3_digest_fallback(req);
-+}
-+
-+static int safexcel_hmac_sha3_384_cra_init(struct crypto_tfm *tfm)
-+{
-+ return safexcel_hmac_sha3_cra_init(tfm, "sha3-384");
-+}
-+
-+struct safexcel_alg_template safexcel_alg_hmac_sha3_384 = {
-+ .type = SAFEXCEL_ALG_TYPE_AHASH,
-+ .algo_mask = SAFEXCEL_ALG_SHA3,
-+ .alg.ahash = {
-+ .init = safexcel_hmac_sha3_384_init,
-+ .update = safexcel_sha3_update,
-+ .final = safexcel_sha3_final,
-+ .finup = safexcel_sha3_finup,
-+ .digest = safexcel_hmac_sha3_384_digest,
-+ .setkey = safexcel_hmac_sha3_setkey,
-+ .export = safexcel_sha3_export,
-+ .import = safexcel_sha3_import,
-+ .halg = {
-+ .digestsize = SHA3_384_DIGEST_SIZE,
-+ .statesize = sizeof(struct safexcel_ahash_export_state),
-+ .base = {
-+ .cra_name = "hmac(sha3-384)",
-+ .cra_driver_name = "safexcel-hmac-sha3-384",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY |
-+ CRYPTO_ALG_NEED_FALLBACK,
-+ .cra_blocksize = SHA3_384_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
-+ .cra_init = safexcel_hmac_sha3_384_cra_init,
-+ .cra_exit = safexcel_hmac_sha3_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+ },
-+};
-+
-+static int safexcel_hmac_sha3_512_init(struct ahash_request *areq)
-+{
-+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
-+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
-+ struct safexcel_ahash_req *req = ahash_request_ctx(areq);
-+
-+ memset(req, 0, sizeof(*req));
-+
-+ /* Copy (half of) the key */
-+ memcpy(req->state, ctx->ipad, SHA3_512_BLOCK_SIZE / 2);
-+ /* Start of HMAC should have len == processed == blocksize */
-+ req->len = SHA3_512_BLOCK_SIZE;
-+ req->processed = SHA3_512_BLOCK_SIZE;
-+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA3_512;
-+ req->digest = CONTEXT_CONTROL_DIGEST_HMAC;
-+ req->state_sz = SHA3_512_BLOCK_SIZE / 2;
-+ req->digest_sz = SHA3_512_DIGEST_SIZE;
-+ req->block_sz = SHA3_512_BLOCK_SIZE;
-+ req->hmac = true;
-+ ctx->do_fallback = false;
-+ ctx->fb_init_done = false;
-+ return 0;
-+}
-+
-+static int safexcel_hmac_sha3_512_digest(struct ahash_request *req)
-+{
-+ if (req->nbytes)
-+ return safexcel_hmac_sha3_512_init(req) ?:
-+ safexcel_ahash_finup(req);
-+
-+ /* HW cannot do zero length HMAC, use fallback instead */
-+ return safexcel_sha3_digest_fallback(req);
-+}
-+
-+static int safexcel_hmac_sha3_512_cra_init(struct crypto_tfm *tfm)
-+{
-+ return safexcel_hmac_sha3_cra_init(tfm, "sha3-512");
-+}
-+struct safexcel_alg_template safexcel_alg_hmac_sha3_512 = {
-+ .type = SAFEXCEL_ALG_TYPE_AHASH,
-+ .algo_mask = SAFEXCEL_ALG_SHA3,
-+ .alg.ahash = {
-+ .init = safexcel_hmac_sha3_512_init,
-+ .update = safexcel_sha3_update,
-+ .final = safexcel_sha3_final,
-+ .finup = safexcel_sha3_finup,
-+ .digest = safexcel_hmac_sha3_512_digest,
-+ .setkey = safexcel_hmac_sha3_setkey,
-+ .export = safexcel_sha3_export,
-+ .import = safexcel_sha3_import,
-+ .halg = {
-+ .digestsize = SHA3_512_DIGEST_SIZE,
-+ .statesize = sizeof(struct safexcel_ahash_export_state),
-+ .base = {
-+ .cra_name = "hmac(sha3-512)",
-+ .cra_driver_name = "safexcel-hmac-sha3-512",
-+ .cra_priority = SAFEXCEL_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY |
-+ CRYPTO_ALG_NEED_FALLBACK,
-+ .cra_blocksize = SHA3_512_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
-+ .cra_init = safexcel_hmac_sha3_512_cra_init,
-+ .cra_exit = safexcel_hmac_sha3_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
- },
- };
---- a/drivers/crypto/inside-secure/safexcel_ring.c
-+++ b/drivers/crypto/inside-secure/safexcel_ring.c
-@@ -14,7 +14,12 @@ int safexcel_init_ring_descriptors(struc
- struct safexcel_desc_ring *cdr,
- struct safexcel_desc_ring *rdr)
- {
-- cdr->offset = sizeof(u32) * priv->config.cd_offset;
-+ int i;
-+ struct safexcel_command_desc *cdesc;
-+ dma_addr_t atok;
-+
-+ /* Actual command descriptor ring */
-+ cdr->offset = priv->config.cd_offset;
- cdr->base = dmam_alloc_coherent(priv->dev,
- cdr->offset * EIP197_DEFAULT_RING_SIZE,
- &cdr->base_dma, GFP_KERNEL);
-@@ -24,7 +29,34 @@ int safexcel_init_ring_descriptors(struc
- cdr->base_end = cdr->base + cdr->offset * (EIP197_DEFAULT_RING_SIZE - 1);
- cdr->read = cdr->base;
-
-- rdr->offset = sizeof(u32) * priv->config.rd_offset;
-+ /* Command descriptor shadow ring for storing additional token data */
-+ cdr->shoffset = priv->config.cdsh_offset;
-+ cdr->shbase = dmam_alloc_coherent(priv->dev,
-+ cdr->shoffset *
-+ EIP197_DEFAULT_RING_SIZE,
-+ &cdr->shbase_dma, GFP_KERNEL);
-+ if (!cdr->shbase)
-+ return -ENOMEM;
-+ cdr->shwrite = cdr->shbase;
-+ cdr->shbase_end = cdr->shbase + cdr->shoffset *
-+ (EIP197_DEFAULT_RING_SIZE - 1);
-+
-+ /*
-+ * Populate command descriptors with physical pointers to shadow descs.
-+ * Note that we only need to do this once if we don't overwrite them.
-+ */
-+ cdesc = cdr->base;
-+ atok = cdr->shbase_dma;
-+ for (i = 0; i < EIP197_DEFAULT_RING_SIZE; i++) {
-+ cdesc->atok_lo = lower_32_bits(atok);
-+ cdesc->atok_hi = upper_32_bits(atok);
-+ cdesc = (void *)cdesc + cdr->offset;
-+ atok += cdr->shoffset;
-+ }
-+
-+ rdr->offset = priv->config.rd_offset;
-+ /* Use shoffset for result token offset here */
-+ rdr->shoffset = priv->config.res_offset;
- rdr->base = dmam_alloc_coherent(priv->dev,
- rdr->offset * EIP197_DEFAULT_RING_SIZE,
- &rdr->base_dma, GFP_KERNEL);
-@@ -42,11 +74,40 @@ inline int safexcel_select_ring(struct s
- return (atomic_inc_return(&priv->ring_used) % priv->config.rings);
- }
-
--static void *safexcel_ring_next_wptr(struct safexcel_crypto_priv *priv,
-- struct safexcel_desc_ring *ring)
-+static void *safexcel_ring_next_cwptr(struct safexcel_crypto_priv *priv,
-+ struct safexcel_desc_ring *ring,
-+ bool first,
-+ struct safexcel_token **atoken)
- {
- void *ptr = ring->write;
-
-+ if (first)
-+ *atoken = ring->shwrite;
-+
-+ if ((ring->write == ring->read - ring->offset) ||
-+ (ring->read == ring->base && ring->write == ring->base_end))
-+ return ERR_PTR(-ENOMEM);
-+
-+ if (ring->write == ring->base_end) {
-+ ring->write = ring->base;
-+ ring->shwrite = ring->shbase;
-+ } else {
-+ ring->write += ring->offset;
-+ ring->shwrite += ring->shoffset;
-+ }
-+
-+ return ptr;
-+}
-+
-+static void *safexcel_ring_next_rwptr(struct safexcel_crypto_priv *priv,
-+ struct safexcel_desc_ring *ring,
-+ struct result_data_desc **rtoken)
-+{
-+ void *ptr = ring->write;
-+
-+ /* Result token at relative offset shoffset */
-+ *rtoken = ring->write + ring->shoffset;
-+
- if ((ring->write == ring->read - ring->offset) ||
- (ring->read == ring->base && ring->write == ring->base_end))
- return ERR_PTR(-ENOMEM);
-@@ -106,10 +167,13 @@ void safexcel_ring_rollback_wptr(struct
- if (ring->write == ring->read)
- return;
-
-- if (ring->write == ring->base)
-+ if (ring->write == ring->base) {
- ring->write = ring->base_end;
-- else
-+ ring->shwrite = ring->shbase_end;
-+ } else {
- ring->write -= ring->offset;
-+ ring->shwrite -= ring->shoffset;
-+ }
- }
-
- struct safexcel_command_desc *safexcel_add_cdesc(struct safexcel_crypto_priv *priv,
-@@ -117,26 +181,26 @@ struct safexcel_command_desc *safexcel_a
- bool first, bool last,
- dma_addr_t data, u32 data_len,
- u32 full_data_len,
-- dma_addr_t context) {
-+ dma_addr_t context,
-+ struct safexcel_token **atoken)
-+{
- struct safexcel_command_desc *cdesc;
-- int i;
-
-- cdesc = safexcel_ring_next_wptr(priv, &priv->ring[ring_id].cdr);
-+ cdesc = safexcel_ring_next_cwptr(priv, &priv->ring[ring_id].cdr,
-+ first, atoken);
- if (IS_ERR(cdesc))
- return cdesc;
-
-- memset(cdesc, 0, sizeof(struct safexcel_command_desc));
--
-- cdesc->first_seg = first;
-- cdesc->last_seg = last;
- cdesc->particle_size = data_len;
-+ cdesc->rsvd0 = 0;
-+ cdesc->last_seg = last;
-+ cdesc->first_seg = first;
-+ cdesc->additional_cdata_size = 0;
-+ cdesc->rsvd1 = 0;
- cdesc->data_lo = lower_32_bits(data);
- cdesc->data_hi = upper_32_bits(data);
-
-- if (first && context) {
-- struct safexcel_token *token =
-- (struct safexcel_token *)cdesc->control_data.token;
--
-+ if (first) {
- /*
- * Note that the length here MUST be >0 or else the EIP(1)97
- * may hang. Newer EIP197 firmware actually incorporates this
-@@ -146,20 +210,12 @@ struct safexcel_command_desc *safexcel_a
- cdesc->control_data.packet_length = full_data_len ?: 1;
- cdesc->control_data.options = EIP197_OPTION_MAGIC_VALUE |
- EIP197_OPTION_64BIT_CTX |
-- EIP197_OPTION_CTX_CTRL_IN_CMD;
-- cdesc->control_data.context_lo =
-- (lower_32_bits(context) & GENMASK(31, 2)) >> 2;
-+ EIP197_OPTION_CTX_CTRL_IN_CMD |
-+ EIP197_OPTION_RC_AUTO;
-+ cdesc->control_data.type = EIP197_TYPE_BCLA;
-+ cdesc->control_data.context_lo = lower_32_bits(context) |
-+ EIP197_CONTEXT_SMALL;
- cdesc->control_data.context_hi = upper_32_bits(context);
--
-- if (priv->version == EIP197B_MRVL ||
-- priv->version == EIP197D_MRVL)
-- cdesc->control_data.options |= EIP197_OPTION_RC_AUTO;
--
-- /* TODO: large xform HMAC with SHA-384/512 uses refresh = 3 */
-- cdesc->control_data.refresh = 2;
--
-- for (i = 0; i < EIP197_MAX_TOKENS; i++)
-- eip197_noop_token(&token[i]);
- }
-
- return cdesc;
-@@ -171,18 +227,27 @@ struct safexcel_result_desc *safexcel_ad
- dma_addr_t data, u32 len)
- {
- struct safexcel_result_desc *rdesc;
-+ struct result_data_desc *rtoken;
-
-- rdesc = safexcel_ring_next_wptr(priv, &priv->ring[ring_id].rdr);
-+ rdesc = safexcel_ring_next_rwptr(priv, &priv->ring[ring_id].rdr,
-+ &rtoken);
- if (IS_ERR(rdesc))
- return rdesc;
-
-- memset(rdesc, 0, sizeof(struct safexcel_result_desc));
--
-- rdesc->first_seg = first;
-- rdesc->last_seg = last;
- rdesc->particle_size = len;
-+ rdesc->rsvd0 = 0;
-+ rdesc->descriptor_overflow = 0;
-+ rdesc->buffer_overflow = 0;
-+ rdesc->last_seg = last;
-+ rdesc->first_seg = first;
-+ rdesc->result_size = EIP197_RD64_RESULT_SIZE;
-+ rdesc->rsvd1 = 0;
- rdesc->data_lo = lower_32_bits(data);
- rdesc->data_hi = upper_32_bits(data);
-
-+ /* Clear length & error code in result token */
-+ rtoken->packet_length = 0;
-+ rtoken->error_code = 0;
-+
- return rdesc;
- }
diff --git a/target/linux/mediatek/patches-5.4/0501-crypto-add-eip97-inside-secure-support.patch b/target/linux/mediatek/patches-5.4/0501-crypto-add-eip97-inside-secure-support.patch
deleted file mode 100644
index 3eda4f291a..0000000000
--- a/target/linux/mediatek/patches-5.4/0501-crypto-add-eip97-inside-secure-support.patch
+++ /dev/null
@@ -1,27 +0,0 @@
---- a/drivers/crypto/inside-secure/safexcel.c
-+++ b/drivers/crypto/inside-secure/safexcel.c
-@@ -595,6 +595,14 @@ static int safexcel_hw_init(struct safex
- val |= EIP197_MST_CTRL_TX_MAX_CMD(5);
- writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
- }
-+ /*
-+ * Set maximum number of TX commands to 2^4 = 16 for EIP97 HW2.1/HW2.3
-+ */
-+ else {
-+ val = 0;
-+ val |= EIP97_MST_CTRL_TX_MAX_CMD(4);
-+ writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
-+ }
-
- /* Configure wr/rd cache values */
- writel(EIP197_MST_CTRL_RD_CACHE(RD_CACHE_4BITS) |
---- a/drivers/crypto/inside-secure/safexcel.h
-+++ b/drivers/crypto/inside-secure/safexcel.h
-@@ -306,6 +306,7 @@
- #define EIP197_MST_CTRL_RD_CACHE(n) (((n) & 0xf) << 0)
- #define EIP197_MST_CTRL_WD_CACHE(n) (((n) & 0xf) << 4)
- #define EIP197_MST_CTRL_TX_MAX_CMD(n) (((n) & 0xf) << 20)
-+#define EIP97_MST_CTRL_TX_MAX_CMD(n) (((n) & 0xf) << 4)
- #define EIP197_MST_CTRL_BYTE_SWAP BIT(24)
- #define EIP197_MST_CTRL_NO_BYTE_SWAP BIT(25)
- #define EIP197_MST_CTRL_BYTE_SWAP_BITS GENMASK(25, 24)
diff --git a/target/linux/mediatek/patches-5.4/0502-dts-mt7623-eip97-inside-secure-support.patch b/target/linux/mediatek/patches-5.4/0502-dts-mt7623-eip97-inside-secure-support.patch
deleted file mode 100644
index 06077fb984..0000000000
--- a/target/linux/mediatek/patches-5.4/0502-dts-mt7623-eip97-inside-secure-support.patch
+++ /dev/null
@@ -1,23 +0,0 @@
---- a/arch/arm/boot/dts/mt7623.dtsi
-+++ b/arch/arm/boot/dts/mt7623.dtsi
-@@ -1047,17 +1047,14 @@
- };
-
- crypto: crypto@1b240000 {
-- compatible = "mediatek,eip97-crypto";
-+ compatible = "inside-secure,safexcel-eip97";
- reg = <0 0x1b240000 0 0x20000>;
- interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_LOW>,
- <GIC_SPI 83 IRQ_TYPE_LEVEL_LOW>,
- <GIC_SPI 84 IRQ_TYPE_LEVEL_LOW>,
-- <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>,
-- <GIC_SPI 97 IRQ_TYPE_LEVEL_LOW>;
-+ <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
-+ interrupt-names = "ring0", "ring1", "ring2", "ring3";
- clocks = <&ethsys CLK_ETHSYS_CRYPTO>;
-- clock-names = "cryp";
-- power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
-- status = "disabled";
- };
-
- bdpsys: syscon@1c000000 {
diff --git a/target/linux/mediatek/patches-5.4/0503-crypto-fix-eip97-cache-incoherent.patch b/target/linux/mediatek/patches-5.4/0503-crypto-fix-eip97-cache-incoherent.patch
deleted file mode 100644
index 5bc0fd0b7d..0000000000
--- a/target/linux/mediatek/patches-5.4/0503-crypto-fix-eip97-cache-incoherent.patch
+++ /dev/null
@@ -1,26 +0,0 @@
---- a/drivers/crypto/inside-secure/safexcel.h
-+++ b/drivers/crypto/inside-secure/safexcel.h
-@@ -722,6 +722,9 @@ enum safexcel_eip_version {
- /* Priority we use for advertising our algorithms */
- #define SAFEXCEL_CRA_PRIORITY 300
-
-+/* System cache line size */
-+#define SYSTEM_CACHELINE_SIZE 64
-+
- /* SM3 digest result for zero length message */
- #define EIP197_SM3_ZEROM_HASH "\x1A\xB2\x1D\x83\x55\xCF\xA1\x7F" \
- "\x8E\x61\x19\x48\x31\xE8\x1A\x8F" \
---- a/drivers/crypto/inside-secure/safexcel_hash.c
-+++ b/drivers/crypto/inside-secure/safexcel_hash.c
-@@ -57,9 +57,9 @@ struct safexcel_ahash_req {
- u8 block_sz; /* block size, only set once */
- u8 digest_sz; /* output digest size, only set once */
- __le32 state[SHA3_512_BLOCK_SIZE /
-- sizeof(__le32)] __aligned(sizeof(__le32));
-+ sizeof(__le32)] __aligned(SYSTEM_CACHELINE_SIZE);
-
-- u64 len;
-+ u64 len __aligned(SYSTEM_CACHELINE_SIZE);
- u64 processed;
-
- u8 cache[HASH_CACHE_SIZE] __aligned(sizeof(u32));
diff --git a/target/linux/mediatek/patches-5.4/0600-net-phylink-propagate-resolved-link-config-via-mac_l.patch b/target/linux/mediatek/patches-5.4/0600-net-phylink-propagate-resolved-link-config-via-mac_l.patch
deleted file mode 100644
index bd854613b7..0000000000
--- a/target/linux/mediatek/patches-5.4/0600-net-phylink-propagate-resolved-link-config-via-mac_l.patch
+++ /dev/null
@@ -1,246 +0,0 @@
-From: Russell King <rmk+kernel@armlinux.org.uk>
-Date: Wed, 26 Feb 2020 10:23:41 +0000
-Subject: [PATCH] net: phylink: propagate resolved link config via
- mac_link_up()
-
-Propagate the resolved link parameters via the mac_link_up() call for
-MACs that do not automatically track their PCS state. We propagate the
-link parameters via function arguments so that inappropriate members
-of struct phylink_link_state can't be accessed, and creating a new
-structure just for this adds needless complexity to the API.
-
-Tested-by: Andre Przywara <andre.przywara@arm.com>
-Tested-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
-Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/Documentation/networking/sfp-phylink.rst
-+++ b/Documentation/networking/sfp-phylink.rst
-@@ -74,10 +74,13 @@ phylib to the sfp/phylink support. Plea
- this documentation.
-
- 1. Optionally split the network driver's phylib update function into
-- three parts dealing with link-down, link-up and reconfiguring the
-- MAC settings. This can be done as a separate preparation commit.
-+ two parts dealing with link-down and link-up. This can be done as
-+ a separate preparation commit.
-
-- An example of this preparation can be found in git commit fc548b991fb0.
-+ An older example of this preparation can be found in git commit
-+ fc548b991fb0, although this was splitting into three parts; the
-+ link-up part now includes configuring the MAC for the link settings.
-+ Please see :c:func:`mac_link_up` for more information on this.
-
- 2. Replace::
-
-@@ -207,6 +210,14 @@ this documentation.
- using. This is particularly important for in-band negotiation
- methods such as 1000base-X and SGMII.
-
-+ The :c:func:`mac_link_up` method is used to inform the MAC that the
-+ link has come up. The call includes the negotiation mode and interface
-+ for reference only. The finalised link parameters are also supplied
-+ (speed, duplex and flow control/pause enablement settings) which
-+ should be used to configure the MAC when the MAC and PCS are not
-+ tightly integrated, or when the settings are not coming from in-band
-+ negotiation.
-+
- The :c:func:`mac_config` method is used to update the MAC with the
- requested state, and must avoid unnecessarily taking the link down
- when making changes to the MAC configuration. This means the
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -3655,9 +3655,11 @@ static void mvneta_mac_link_down(struct
- mvneta_set_eee(pp, false);
- }
-
--static void mvneta_mac_link_up(struct phylink_config *config, unsigned int mode,
-- phy_interface_t interface,
-- struct phy_device *phy)
-+static void mvneta_mac_link_up(struct phylink_config *config,
-+ struct phy_device *phy,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex,
-+ bool tx_pause, bool rx_pause)
- {
- struct net_device *ndev = to_net_dev(config->dev);
- struct mvneta_port *pp = netdev_priv(ndev);
---- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
-+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
-@@ -58,8 +58,11 @@ static struct {
- */
- static void mvpp2_mac_config(struct phylink_config *config, unsigned int mode,
- const struct phylink_link_state *state);
--static void mvpp2_mac_link_up(struct phylink_config *config, unsigned int mode,
-- phy_interface_t interface, struct phy_device *phy);
-+static void mvpp2_mac_link_up(struct phylink_config *config,
-+ struct phy_device *phy,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex,
-+ bool tx_pause, bool rx_pause);
-
- /* Queue modes */
- #define MVPP2_QDIST_SINGLE_MODE 0
-@@ -3468,8 +3471,9 @@ static void mvpp2_start_dev(struct mvpp2
- .interface = port->phy_interface,
- };
- mvpp2_mac_config(&port->phylink_config, MLO_AN_INBAND, &state);
-- mvpp2_mac_link_up(&port->phylink_config, MLO_AN_INBAND,
-- port->phy_interface, NULL);
-+ mvpp2_mac_link_up(&port->phylink_config, NULL,
-+ MLO_AN_INBAND, port->phy_interface,
-+ SPEED_UNKNOWN, DUPLEX_UNKNOWN, false, false);
- }
-
- netif_tx_start_all_queues(port->dev);
-@@ -5137,8 +5141,11 @@ static void mvpp2_mac_config(struct phyl
- mvpp2_port_enable(port);
- }
-
--static void mvpp2_mac_link_up(struct phylink_config *config, unsigned int mode,
-- phy_interface_t interface, struct phy_device *phy)
-+static void mvpp2_mac_link_up(struct phylink_config *config,
-+ struct phy_device *phy,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex,
-+ bool tx_pause, bool rx_pause)
- {
- struct mvpp2_port *port = mvpp2_phylink_to_port(config);
- u32 val;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -449,9 +449,10 @@ static void mtk_mac_link_down(struct phy
- mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
- }
-
--static void mtk_mac_link_up(struct phylink_config *config, unsigned int mode,
-- phy_interface_t interface,
-- struct phy_device *phy)
-+static void mtk_mac_link_up(struct phylink_config *config,
-+ struct phy_device *phy,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex, bool tx_pause, bool rx_pause)
- {
- struct mtk_mac *mac = container_of(config, struct mtk_mac,
- phylink_config);
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -925,8 +925,10 @@ static void stmmac_mac_link_down(struct
- }
-
- static void stmmac_mac_link_up(struct phylink_config *config,
-+ struct phy_device *phy,
- unsigned int mode, phy_interface_t interface,
-- struct phy_device *phy)
-+ int speed, int duplex,
-+ bool tx_pause, bool rx_pause)
- {
- struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
-
---- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
-+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
-@@ -1499,9 +1499,10 @@ static void axienet_mac_link_down(struct
- }
-
- static void axienet_mac_link_up(struct phylink_config *config,
-- unsigned int mode,
-- phy_interface_t interface,
-- struct phy_device *phy)
-+ struct phy_device *phy,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex,
-+ bool tx_pause, bool rx_pause)
- {
- /* nothing meaningful to do */
- }
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -447,8 +447,11 @@ static void phylink_mac_link_up(struct p
- struct net_device *ndev = pl->netdev;
-
- pl->cur_interface = link_state.interface;
-- pl->ops->mac_link_up(pl->config, pl->cur_link_an_mode,
-- pl->cur_interface, pl->phydev);
-+ pl->ops->mac_link_up(pl->config, pl->phydev,
-+ pl->cur_link_an_mode, pl->cur_interface,
-+ link_state.speed, link_state.duplex,
-+ !!(link_state.pause & MLO_PAUSE_TX),
-+ !!(link_state.pause & MLO_PAUSE_RX));
-
- if (ndev)
- netif_carrier_on(ndev);
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -91,9 +91,10 @@ struct phylink_mac_ops {
- void (*mac_an_restart)(struct phylink_config *config);
- void (*mac_link_down)(struct phylink_config *config, unsigned int mode,
- phy_interface_t interface);
-- void (*mac_link_up)(struct phylink_config *config, unsigned int mode,
-- phy_interface_t interface,
-- struct phy_device *phy);
-+ void (*mac_link_up)(struct phylink_config *config,
-+ struct phy_device *phy, unsigned int mode,
-+ phy_interface_t interface, int speed, int duplex,
-+ bool tx_pause, bool rx_pause);
- };
-
- #if 0 /* For kernel-doc purposes only. */
-@@ -217,19 +218,34 @@ void mac_link_down(struct phylink_config
- /**
- * mac_link_up() - allow the link to come up
- * @config: a pointer to a &struct phylink_config.
-+ * @phy: any attached phy
- * @mode: link autonegotiation mode
- * @interface: link &typedef phy_interface_t mode
-- * @phy: any attached phy
-+ * @speed: link speed
-+ * @duplex: link duplex
-+ * @tx_pause: link transmit pause enablement status
-+ * @rx_pause: link receive pause enablement status
-+ *
-+ * Configure the MAC for an established link.
-+ *
-+ * @speed, @duplex, @tx_pause and @rx_pause indicate the finalised link
-+ * settings, and should be used to configure the MAC block appropriately
-+ * where these settings are not automatically conveyed from the PCS block,
-+ * or if in-band negotiation (as defined by phylink_autoneg_inband(@mode))
-+ * is disabled.
-+ *
-+ * Note that when 802.3z in-band negotiation is in use, it is possible
-+ * that the user wishes to override the pause settings, and this should
-+ * be allowed when considering the implementation of this method.
- *
-- * If @mode is not an in-band negotiation mode (as defined by
-- * phylink_autoneg_inband()), allow the link to come up. If @phy
-- * is non-%NULL, configure Energy Efficient Ethernet by calling
-+ * If in-band negotiation mode is disabled, allow the link to come up. If
-+ * @phy is non-%NULL, configure Energy Efficient Ethernet by calling
- * phy_init_eee() and perform appropriate MAC configuration for EEE.
- * Interface type selection must be done in mac_config().
- */
--void mac_link_up(struct phylink_config *config, unsigned int mode,
-- phy_interface_t interface,
-- struct phy_device *phy);
-+void mac_link_up(struct phylink_config *config, struct phy_device *phy,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex, bool tx_pause, bool rx_pause);
- #endif
-
- struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *,
---- a/net/dsa/port.c
-+++ b/net/dsa/port.c
-@@ -529,9 +529,11 @@ void dsa_port_phylink_mac_link_down(stru
- EXPORT_SYMBOL_GPL(dsa_port_phylink_mac_link_down);
-
- void dsa_port_phylink_mac_link_up(struct phylink_config *config,
-+ struct phy_device *phydev,
- unsigned int mode,
- phy_interface_t interface,
-- struct phy_device *phydev)
-+ int speed, int duplex,
-+ bool tx_pause, bool rx_pause)
- {
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
- struct dsa_switch *ds = dp->ds;
diff --git a/target/linux/mediatek/patches-5.4/0601-net-dsa-propagate-resolved-link-config-via-mac_link_.patch b/target/linux/mediatek/patches-5.4/0601-net-dsa-propagate-resolved-link-config-via-mac_link_.patch
deleted file mode 100644
index 0df300b627..0000000000
--- a/target/linux/mediatek/patches-5.4/0601-net-dsa-propagate-resolved-link-config-via-mac_link_.patch
+++ /dev/null
@@ -1,143 +0,0 @@
-From: Russell King <rmk+kernel@armlinux.org.uk>
-Date: Wed, 26 Feb 2020 10:23:46 +0000
-Subject: [PATCH] net: dsa: propagate resolved link config via mac_link_up()
-
-Propagate the resolved link configuration down via DSA's
-phylink_mac_link_up() operation to allow split PCS/MAC to work.
-
-Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1284,7 +1284,9 @@ EXPORT_SYMBOL(b53_phylink_mac_link_down)
- void b53_phylink_mac_link_up(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface,
-- struct phy_device *phydev)
-+ struct phy_device *phydev,
-+ int speed, int duplex,
-+ bool tx_pause, bool rx_pause)
- {
- struct b53_device *dev = ds->priv;
-
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -337,7 +337,9 @@ void b53_phylink_mac_link_down(struct ds
- void b53_phylink_mac_link_up(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface,
-- struct phy_device *phydev);
-+ struct phy_device *phydev,
-+ int speed, int duplex,
-+ bool tx_pause, bool rx_pause);
- int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering);
- int b53_vlan_prepare(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_vlan *vlan);
---- a/drivers/net/dsa/bcm_sf2.c
-+++ b/drivers/net/dsa/bcm_sf2.c
-@@ -636,7 +636,9 @@ static void bcm_sf2_sw_mac_link_down(str
- static void bcm_sf2_sw_mac_link_up(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface,
-- struct phy_device *phydev)
-+ struct phy_device *phydev,
-+ int speed, int duplex,
-+ bool tx_pause, bool rx_pause)
- {
- struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
- struct ethtool_eee *p = &priv->dev->ports[port].eee;
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1663,7 +1663,9 @@ static void gswip_phylink_mac_link_down(
- static void gswip_phylink_mac_link_up(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface,
-- struct phy_device *phydev)
-+ struct phy_device *phydev,
-+ int speed, int duplex,
-+ bool tx_pause, bool rx_pause)
- {
- struct gswip_priv *priv = ds->priv;
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -1440,7 +1440,9 @@ static void mt7530_phylink_mac_link_down
- static void mt7530_phylink_mac_link_up(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface,
-- struct phy_device *phydev)
-+ struct phy_device *phydev,
-+ int speed, int duplex,
-+ bool tx_pause, bool rx_pause)
- {
- struct mt7530_priv *priv = ds->priv;
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -652,7 +652,9 @@ static void mv88e6xxx_mac_link_down(stru
-
- static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
- unsigned int mode, phy_interface_t interface,
-- struct phy_device *phydev)
-+ struct phy_device *phydev,
-+ int speed, int duplex,
-+ bool tx_pause, bool rx_pause)
- {
- if (mode == MLO_AN_FIXED)
- mv88e6xxx_mac_link_force(ds, port, LINK_FORCED_UP);
---- a/drivers/net/dsa/sja1105/sja1105_main.c
-+++ b/drivers/net/dsa/sja1105/sja1105_main.c
-@@ -831,7 +831,9 @@ static void sja1105_mac_link_down(struct
- static void sja1105_mac_link_up(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface,
-- struct phy_device *phydev)
-+ struct phy_device *phydev,
-+ int speed, int duplex,
-+ bool tx_pause, bool rx_pause)
- {
- sja1105_inhibit_tx(ds->priv, BIT(port), false);
- }
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -406,7 +406,9 @@ struct dsa_switch_ops {
- void (*phylink_mac_link_up)(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface,
-- struct phy_device *phydev);
-+ struct phy_device *phydev,
-+ int speed, int duplex,
-+ bool tx_pause, bool rx_pause);
- void (*phylink_fixed_state)(struct dsa_switch *ds, int port,
- struct phylink_link_state *state);
- /*
---- a/net/dsa/port.c
-+++ b/net/dsa/port.c
-@@ -544,7 +544,8 @@ void dsa_port_phylink_mac_link_up(struct
- return;
- }
-
-- ds->ops->phylink_mac_link_up(ds, dp->index, mode, interface, phydev);
-+ ds->ops->phylink_mac_link_up(ds, dp->index, mode, interface, phydev,
-+ speed, duplex, tx_pause, rx_pause);
- }
- EXPORT_SYMBOL_GPL(dsa_port_phylink_mac_link_up);
-
---- a/net/dsa/dsa_priv.h
-+++ b/net/dsa/dsa_priv.h
-@@ -192,9 +192,11 @@ void dsa_port_phylink_mac_link_down(stru
- unsigned int mode,
- phy_interface_t interface);
- void dsa_port_phylink_mac_link_up(struct phylink_config *config,
-+ struct phy_device *phydev,
- unsigned int mode,
- phy_interface_t interface,
-- struct phy_device *phydev);
-+ int speed, int duplex,
-+ bool tx_pause, bool rx_pause);
- extern const struct phylink_mac_ops dsa_port_phylink_mac_ops;
-
- /* slave.c */
diff --git a/target/linux/mediatek/patches-5.4/0602-net-dsa-mt7530-use-resolved-link-config-in-mac_link_.patch b/target/linux/mediatek/patches-5.4/0602-net-dsa-mt7530-use-resolved-link-config-in-mac_link_.patch
deleted file mode 100644
index 23fba85252..0000000000
--- a/target/linux/mediatek/patches-5.4/0602-net-dsa-mt7530-use-resolved-link-config-in-mac_link_.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= <opensource@vdorst.com>
-Date: Fri, 27 Mar 2020 15:44:12 +0100
-Subject: [PATCH] net: dsa: mt7530: use resolved link config in mac_link_up()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Convert the mt7530 switch driver to use the finalised link
-parameters in mac_link_up() rather than the parameters in mac_config().
-
-Signed-off-by: René van Dorst <opensource@vdorst.com>
-Tested-by: Sean Wang <sean.wang@mediatek.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -489,17 +489,6 @@ mt7530_mib_reset(struct dsa_switch *ds)
- mt7530_write(priv, MT7530_MIB_CCR, CCR_MIB_ACTIVATE);
- }
-
--static void
--mt7530_port_set_status(struct mt7530_priv *priv, int port, int enable)
--{
-- u32 mask = PMCR_TX_EN | PMCR_RX_EN | PMCR_FORCE_LNK;
--
-- if (enable)
-- mt7530_set(priv, MT7530_PMCR_P(port), mask);
-- else
-- mt7530_clear(priv, MT7530_PMCR_P(port), mask);
--}
--
- static int mt7530_phy_read(struct dsa_switch *ds, int port, int regnum)
- {
- struct mt7530_priv *priv = ds->priv;
-@@ -673,7 +662,7 @@ mt7530_port_enable(struct dsa_switch *ds
- priv->ports[port].enable = true;
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
- priv->ports[port].pm);
-- mt7530_port_set_status(priv, port, 0);
-+ mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
-
- mutex_unlock(&priv->reg_mutex);
-
-@@ -696,7 +685,7 @@ mt7530_port_disable(struct dsa_switch *d
- priv->ports[port].enable = false;
- mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
- PCR_MATRIX_CLR);
-- mt7530_port_set_status(priv, port, 0);
-+ mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
-
- mutex_unlock(&priv->reg_mutex);
- }
-@@ -1395,8 +1384,7 @@ static void mt7530_phylink_mac_config(st
-
- mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
- mcr_new = mcr_cur;
-- mcr_new &= ~(PMCR_FORCE_SPEED_1000 | PMCR_FORCE_SPEED_100 |
-- PMCR_FORCE_FDX | PMCR_TX_FC_EN | PMCR_RX_FC_EN);
-+ mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
- mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN |
- PMCR_BACKPR_EN | PMCR_FORCE_MODE;
-
-@@ -1404,26 +1392,6 @@ static void mt7530_phylink_mac_config(st
- if (port == 5 && dsa_is_user_port(ds, 5))
- mcr_new |= PMCR_EXT_PHY;
-
-- switch (state->speed) {
-- case SPEED_1000:
-- mcr_new |= PMCR_FORCE_SPEED_1000;
-- if (priv->eee_enable & BIT(port))
-- mcr_new |= PMCR_FORCE_EEE1G;
-- break;
-- case SPEED_100:
-- mcr_new |= PMCR_FORCE_SPEED_100;
-- if (priv->eee_enable & BIT(port))
-- mcr_new |= PMCR_FORCE_EEE100;
-- break;
-- }
-- if (state->duplex == DUPLEX_FULL) {
-- mcr_new |= PMCR_FORCE_FDX;
-- if (state->pause & MLO_PAUSE_TX)
-- mcr_new |= PMCR_TX_FC_EN;
-- if (state->pause & MLO_PAUSE_RX)
-- mcr_new |= PMCR_RX_FC_EN;
-- }
--
- if (mcr_new != mcr_cur)
- mt7530_write(priv, MT7530_PMCR_P(port), mcr_new);
- }
-@@ -1434,7 +1402,7 @@ static void mt7530_phylink_mac_link_down
- {
- struct mt7530_priv *priv = ds->priv;
-
-- mt7530_port_set_status(priv, port, 0);
-+ mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
- }
-
- static void mt7530_phylink_mac_link_up(struct dsa_switch *ds, int port,
-@@ -1445,8 +1413,31 @@ static void mt7530_phylink_mac_link_up(s
- bool tx_pause, bool rx_pause)
- {
- struct mt7530_priv *priv = ds->priv;
-+ u32 mcr;
-+
-+ mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
-+
-+ switch (speed) {
-+ case SPEED_1000:
-+ mcr |= PMCR_FORCE_SPEED_1000;
-+ if (priv->eee_enable & BIT(port))
-+ mcr_new |= PMCR_FORCE_EEE1G;
-+ break;
-+ case SPEED_100:
-+ mcr |= PMCR_FORCE_SPEED_100;
-+ if (priv->eee_enable & BIT(port))
-+ mcr_new |= PMCR_FORCE_EEE100;
-+ break;
-+ }
-+ if (duplex == DUPLEX_FULL) {
-+ mcr |= PMCR_FORCE_FDX;
-+ if (tx_pause)
-+ mcr |= PMCR_TX_FC_EN;
-+ if (rx_pause)
-+ mcr |= PMCR_RX_FC_EN;
-+ }
-
-- mt7530_port_set_status(priv, port, 1);
-+ mt7530_set(priv, MT7530_PMCR_P(port), mcr);
- }
-
- static void mt7530_phylink_validate(struct dsa_switch *ds, int port,
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -222,6 +222,10 @@ enum mt7530_vlan_port_attr {
- #define PMCR_FORCE_LNK BIT(0)
- #define PMCR_SPEED_MASK (PMCR_FORCE_SPEED_100 | \
- PMCR_FORCE_SPEED_1000)
-+#define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
-+ PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
-+ PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
-+ PMCR_FORCE_FDX | PMCR_FORCE_LNK)
-
- #define MT7530_PMSR_P(x) (0x3008 + (x) * 0x100)
- #define PMSR_EEE1G BIT(7)
diff --git a/target/linux/mediatek/patches-5.4/0603-net-dsa-mt7530-Extend-device-data-ready-for-adding-a.patch b/target/linux/mediatek/patches-5.4/0603-net-dsa-mt7530-Extend-device-data-ready-for-adding-a.patch
deleted file mode 100644
index 718ed8ea2d..0000000000
--- a/target/linux/mediatek/patches-5.4/0603-net-dsa-mt7530-Extend-device-data-ready-for-adding-a.patch
+++ /dev/null
@@ -1,458 +0,0 @@
-From: Landen Chao <landen.chao@mediatek.com>
-Date: Fri, 4 Sep 2020 22:21:57 +0800
-Subject: [PATCH] net: dsa: mt7530: Extend device data ready for adding a
- new hardware
-
-Add a structure holding required operations for each device such as device
-initialization, PHY port read or write, a checker whether PHY interface is
-supported on a certain port, MAC port setup for either bus pad or a
-specific PHY interface.
-
-The patch is done for ready adding a new hardware MT7531, and keep the
-same setup logic of existing hardware.
-
-Signed-off-by: Landen Chao <landen.chao@mediatek.com>
-Signed-off-by: Sean Wang <sean.wang@mediatek.com>
----
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -373,8 +373,9 @@ mt7530_fdb_write(struct mt7530_priv *pri
- mt7530_write(priv, MT7530_ATA1 + (i * 4), reg[i]);
- }
-
-+/* Setup TX circuit including relevant PAD and driving */
- static int
--mt7530_pad_clk_setup(struct dsa_switch *ds, int mode)
-+mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
- {
- struct mt7530_priv *priv = ds->priv;
- u32 ncpo1, ssc_delta, trgint, i, xtal;
-@@ -388,7 +389,7 @@ mt7530_pad_clk_setup(struct dsa_switch *
- return -EINVAL;
- }
-
-- switch (mode) {
-+ switch (interface) {
- case PHY_INTERFACE_MODE_RGMII:
- trgint = 0;
- /* PLL frequency: 125MHz */
-@@ -410,7 +411,8 @@ mt7530_pad_clk_setup(struct dsa_switch *
- }
- break;
- default:
-- dev_err(priv->dev, "xMII mode %d not supported\n", mode);
-+ dev_err(priv->dev, "xMII interface %d not supported\n",
-+ interface);
- return -EINVAL;
- }
-
-@@ -1332,12 +1334,11 @@ mt7530_setup(struct dsa_switch *ds)
- return 0;
- }
-
--static void mt7530_phylink_mac_config(struct dsa_switch *ds, int port,
-- unsigned int mode,
-- const struct phylink_link_state *state)
-+static bool
-+mt7530_phy_mode_supported(struct dsa_switch *ds, int port,
-+ const struct phylink_link_state *state)
- {
- struct mt7530_priv *priv = ds->priv;
-- u32 mcr_cur, mcr_new;
-
- switch (port) {
- case 0: /* Internal phy */
-@@ -1346,33 +1347,114 @@ static void mt7530_phylink_mac_config(st
- case 3:
- case 4:
- if (state->interface != PHY_INTERFACE_MODE_GMII)
-- return;
-+ goto unsupported;
- break;
- case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
-- if (priv->p5_interface == state->interface)
-- break;
- if (!phy_interface_mode_is_rgmii(state->interface) &&
- state->interface != PHY_INTERFACE_MODE_MII &&
- state->interface != PHY_INTERFACE_MODE_GMII)
-- return;
-+ goto unsupported;
-+ break;
-+ case 6: /* 1st cpu port */
-+ if (state->interface != PHY_INTERFACE_MODE_RGMII &&
-+ state->interface != PHY_INTERFACE_MODE_TRGMII)
-+ goto unsupported;
-+ break;
-+ default:
-+ dev_err(priv->dev, "%s: unsupported port: %i\n", __func__,
-+ port);
-+ goto unsupported;
-+ }
-+
-+ return true;
-+
-+unsupported:
-+ return false;
-+}
-+
-+static bool
-+mt753x_phy_mode_supported(struct dsa_switch *ds, int port,
-+ const struct phylink_link_state *state)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ return priv->info->phy_mode_supported(ds, port, state);
-+}
-+
-+static int
-+mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ return priv->info->pad_setup(ds, state->interface);
-+}
-+
-+static int
-+mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-+ phy_interface_t interface)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ /* Only need to setup port5. */
-+ if (port != 5)
-+ return 0;
-+
-+ mt7530_setup_port5(priv->ds, interface);
-+
-+ return 0;
-+}
-+
-+static int
-+mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-+ const struct phylink_link_state *state)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ return priv->info->mac_port_config(ds, port, mode, state->interface);
-+}
-+
-+static void
-+mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-+ const struct phylink_link_state *state)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ u32 mcr_cur, mcr_new;
-+
-+ if (!mt753x_phy_mode_supported(ds, port, state))
-+ goto unsupported;
-+
-+ switch (port) {
-+ case 0: /* Internal phy */
-+ case 1:
-+ case 2:
-+ case 3:
-+ case 4:
-+ if (state->interface != PHY_INTERFACE_MODE_GMII)
-+ goto unsupported;
-+ break;
-+ case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
-+ if (priv->p5_interface == state->interface)
-+ break;
-+
-+ if (mt753x_mac_config(ds, port, mode, state) < 0)
-+ goto unsupported;
-
-- mt7530_setup_port5(ds, state->interface);
- break;
- case 6: /* 1st cpu port */
- if (priv->p6_interface == state->interface)
- break;
-
-- if (state->interface != PHY_INTERFACE_MODE_RGMII &&
-- state->interface != PHY_INTERFACE_MODE_TRGMII)
-- return;
-+ mt753x_pad_setup(ds, state);
-
-- /* Setup TX circuit incluing relevant PAD and driving */
-- mt7530_pad_clk_setup(ds, state->interface);
-+ if (mt753x_mac_config(ds, port, mode, state) < 0)
-+ goto unsupported;
-
- priv->p6_interface = state->interface;
- break;
- default:
-- dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
-+unsupported:
-+ dev_err(ds->dev, "%s: unsupported %s port: %i\n",
-+ __func__, phy_modes(state->interface), port);
- return;
- }
-
-@@ -1440,61 +1522,44 @@ static void mt7530_phylink_mac_link_up(s
- mt7530_set(priv, MT7530_PMCR_P(port), mcr);
- }
-
--static void mt7530_phylink_validate(struct dsa_switch *ds, int port,
-- unsigned long *supported,
-- struct phylink_link_state *state)
-+static void
-+mt7530_mac_port_validate(struct dsa_switch *ds, int port,
-+ unsigned long *supported)
- {
-+ if (port == 5)
-+ phylink_set(supported, 1000baseX_Full);
-+}
-+
-+static void
-+mt753x_phylink_validate(struct dsa_switch *ds, int port,
-+ unsigned long *supported,
-+ struct phylink_link_state *state)
-+{
-+ struct mt7530_priv *priv = ds->priv;
- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-
-- switch (port) {
-- case 0: /* Internal phy */
-- case 1:
-- case 2:
-- case 3:
-- case 4:
-- if (state->interface != PHY_INTERFACE_MODE_NA &&
-- state->interface != PHY_INTERFACE_MODE_GMII)
-- goto unsupported;
-- break;
-- case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
-- if (state->interface != PHY_INTERFACE_MODE_NA &&
-- !phy_interface_mode_is_rgmii(state->interface) &&
-- state->interface != PHY_INTERFACE_MODE_MII &&
-- state->interface != PHY_INTERFACE_MODE_GMII)
-- goto unsupported;
-- break;
-- case 6: /* 1st cpu port */
-- if (state->interface != PHY_INTERFACE_MODE_NA &&
-- state->interface != PHY_INTERFACE_MODE_RGMII &&
-- state->interface != PHY_INTERFACE_MODE_TRGMII)
-- goto unsupported;
-- break;
-- default:
-- dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
--unsupported:
-+ if (state->interface != PHY_INTERFACE_MODE_NA &&
-+ !mt753x_phy_mode_supported(ds, port, state)) {
- linkmode_zero(supported);
- return;
- }
-
- phylink_set_port_modes(mask);
-- phylink_set(mask, Autoneg);
-
-- if (state->interface == PHY_INTERFACE_MODE_TRGMII) {
-- phylink_set(mask, 1000baseT_Full);
-- } else {
-+ if (state->interface != PHY_INTERFACE_MODE_TRGMII) {
- phylink_set(mask, 10baseT_Half);
- phylink_set(mask, 10baseT_Full);
- phylink_set(mask, 100baseT_Half);
- phylink_set(mask, 100baseT_Full);
--
-- if (state->interface != PHY_INTERFACE_MODE_MII) {
-- /* This switch only supports 1G full-duplex. */
-- phylink_set(mask, 1000baseT_Full);
-- if (port == 5)
-- phylink_set(mask, 1000baseX_Full);
-- }
-+ phylink_set(mask, Autoneg);
- }
-
-+ /* This switch only supports 1G full-duplex. */
-+ if (state->interface != PHY_INTERFACE_MODE_MII)
-+ phylink_set(mask, 1000baseT_Full);
-+
-+ priv->info->mac_port_validate(ds, port, mask);
-+
- phylink_set(mask, Pause);
- phylink_set(mask, Asym_Pause);
-
-@@ -1590,12 +1655,45 @@ static int mt7530_set_mac_eee(struct dsa
- return 0;
- }
-
-+static int
-+mt753x_phylink_mac_link_state(struct dsa_switch *ds, int port,
-+ struct phylink_link_state *state)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ return priv->info->mac_port_get_state(ds, port, state);
-+}
-+
-+static int
-+mt753x_setup(struct dsa_switch *ds)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ return priv->info->sw_setup(ds);
-+}
-+
-+static int
-+mt753x_phy_read(struct dsa_switch *ds, int port, int regnum)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ return priv->info->phy_read(ds, port, regnum);
-+}
-+
-+static int
-+mt753x_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ return priv->info->phy_write(ds, port, regnum, val);
-+}
-+
- static const struct dsa_switch_ops mt7530_switch_ops = {
- .get_tag_protocol = mtk_get_tag_protocol,
-- .setup = mt7530_setup,
-+ .setup = mt753x_setup,
- .get_strings = mt7530_get_strings,
-- .phy_read = mt7530_phy_read,
-- .phy_write = mt7530_phy_write,
-+ .phy_read = mt753x_phy_read,
-+ .phy_write = mt753x_phy_write,
- .get_ethtool_stats = mt7530_get_ethtool_stats,
- .get_sset_count = mt7530_get_sset_count,
- .port_enable = mt7530_port_enable,
-@@ -1612,18 +1710,43 @@ static const struct dsa_switch_ops mt753
- .port_vlan_del = mt7530_port_vlan_del,
- .port_mirror_add = mt7530_port_mirror_add,
- .port_mirror_del = mt7530_port_mirror_del,
-- .phylink_validate = mt7530_phylink_validate,
-- .phylink_mac_link_state = mt7530_phylink_mac_link_state,
-- .phylink_mac_config = mt7530_phylink_mac_config,
-+ .phylink_validate = mt753x_phylink_validate,
-+ .phylink_mac_link_state = mt753x_phylink_mac_link_state,
-+ .phylink_mac_config = mt753x_phylink_mac_config,
- .phylink_mac_link_down = mt7530_phylink_mac_link_down,
- .phylink_mac_link_up = mt7530_phylink_mac_link_up,
- .get_mac_eee = mt7530_get_mac_eee,
- .set_mac_eee = mt7530_set_mac_eee,
- };
-
-+static const struct mt753x_info mt753x_table[] = {
-+ [ID_MT7621] = {
-+ .id = ID_MT7621,
-+ .sw_setup = mt7530_setup,
-+ .phy_read = mt7530_phy_read,
-+ .phy_write = mt7530_phy_write,
-+ .pad_setup = mt7530_pad_clk_setup,
-+ .phy_mode_supported = mt7530_phy_mode_supported,
-+ .mac_port_validate = mt7530_mac_port_validate,
-+ .mac_port_get_state = mt7530_phylink_mac_link_state,
-+ .mac_port_config = mt7530_mac_config,
-+ },
-+ [ID_MT7530] = {
-+ .id = ID_MT7530,
-+ .sw_setup = mt7530_setup,
-+ .phy_read = mt7530_phy_read,
-+ .phy_write = mt7530_phy_write,
-+ .pad_setup = mt7530_pad_clk_setup,
-+ .phy_mode_supported = mt7530_phy_mode_supported,
-+ .mac_port_validate = mt7530_mac_port_validate,
-+ .mac_port_get_state = mt7530_phylink_mac_link_state,
-+ .mac_port_config = mt7530_mac_config,
-+ },
-+};
-+
- static const struct of_device_id mt7530_of_match[] = {
-- { .compatible = "mediatek,mt7621", .data = (void *)ID_MT7621, },
-- { .compatible = "mediatek,mt7530", .data = (void *)ID_MT7530, },
-+ { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
-+ { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
- { /* sentinel */ },
- };
- MODULE_DEVICE_TABLE(of, mt7530_of_match);
-@@ -1661,8 +1784,21 @@ mt7530_probe(struct mdio_device *mdiodev
- /* Get the hardware identifier from the devicetree node.
- * We will need it for some of the clock and regulator setup.
- */
-- priv->id = (unsigned int)(unsigned long)
-- of_device_get_match_data(&mdiodev->dev);
-+ priv->info = of_device_get_match_data(&mdiodev->dev);
-+ if (!priv->info)
-+ return -EINVAL;
-+
-+ /* Sanity check if these required device operations are filled
-+ * properly.
-+ */
-+ if (!priv->info->sw_setup || !priv->info->pad_setup ||
-+ !priv->info->phy_read || !priv->info->phy_write ||
-+ !priv->info->phy_mode_supported ||
-+ !priv->info->mac_port_validate ||
-+ !priv->info->mac_port_get_state || !priv->info->mac_port_config)
-+ return -EINVAL;
-+
-+ priv->id = priv->info->id;
-
- if (priv->id == ID_MT7530) {
- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -11,7 +11,7 @@
- #define MT7530_NUM_FDB_RECORDS 2048
- #define MT7530_ALL_MEMBERS 0xff
-
--enum {
-+enum mt753x_id {
- ID_MT7530 = 0,
- ID_MT7621 = 1,
- };
-@@ -451,6 +451,40 @@ static const char *p5_intf_modes(unsigne
- }
- }
-
-+/* struct mt753x_info - This is the main data structure for holding the specific
-+ * part for each supported device
-+ * @sw_setup: Holding the handler to a device initialization
-+ * @phy_read: Holding the way reading PHY port
-+ * @phy_write: Holding the way writing PHY port
-+ * @pad_setup: Holding the way setting up the bus pad for a certain
-+ * MAC port
-+ * @phy_mode_supported: Check if the PHY type is being supported on a certain
-+ * port
-+ * @mac_port_validate: Holding the way to set addition validate type for a
-+ * certan MAC port
-+ * @mac_port_get_state: Holding the way getting the MAC/PCS state for a certain
-+ * MAC port
-+ * @mac_port_config: Holding the way setting up the PHY attribute to a
-+ * certain MAC port
-+ */
-+struct mt753x_info {
-+ enum mt753x_id id;
-+
-+ int (*sw_setup)(struct dsa_switch *ds);
-+ int (*phy_read)(struct dsa_switch *ds, int port, int regnum);
-+ int (*phy_write)(struct dsa_switch *ds, int port, int regnum, u16 val);
-+ int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface);
-+ bool (*phy_mode_supported)(struct dsa_switch *ds, int port,
-+ const struct phylink_link_state *state);
-+ void (*mac_port_validate)(struct dsa_switch *ds, int port,
-+ unsigned long *supported);
-+ int (*mac_port_get_state)(struct dsa_switch *ds, int port,
-+ struct phylink_link_state *state);
-+ int (*mac_port_config)(struct dsa_switch *ds, int port,
-+ unsigned int mode,
-+ phy_interface_t interface);
-+};
-+
- /* struct mt7530_priv - This is the main data structure for holding the state
- * of the driver
- * @dev: The device pointer
-@@ -476,6 +510,7 @@ struct mt7530_priv {
- struct regulator *core_pwr;
- struct regulator *io_pwr;
- struct gpio_desc *reset;
-+ const struct mt753x_info *info;
- unsigned int id;
- bool mcm;
- phy_interface_t p6_interface;
diff --git a/target/linux/mediatek/patches-5.4/0604-net-dsa-mt7530-Add-the-support-of-MT7531-switch.patch b/target/linux/mediatek/patches-5.4/0604-net-dsa-mt7530-Add-the-support-of-MT7531-switch.patch
deleted file mode 100644
index 8ede862204..0000000000
--- a/target/linux/mediatek/patches-5.4/0604-net-dsa-mt7530-Add-the-support-of-MT7531-switch.patch
+++ /dev/null
@@ -1,1510 +0,0 @@
-From: Landen Chao <landen.chao@mediatek.com>
-Date: Fri, 4 Sep 2020 22:21:59 +0800
-Subject: [PATCH] net: dsa: mt7530: Add the support of MT7531 switch
-
-Add new support for MT7531:
-
-MT7531 is the next generation of MT7530. It is also a 7-ports switch with
-5 giga embedded phys, 2 cpu ports, and the same MAC logic of MT7530. Cpu
-port 6 only supports SGMII interface. Cpu port 5 supports either RGMII
-or SGMII in different HW sku, but cannot be muxed to PHY of port 0/4 like
-mt7530. Due to SGMII interface support, pll, and pad setting are different
-from MT7530. This patch adds different initial setting, and SGMII phylink
-handlers of MT7531.
-
-MT7531 SGMII interface can be configured in following mode:
-- 'SGMII AN mode' with in-band negotiation capability
- which is compatible with PHY_INTERFACE_MODE_SGMII.
-- 'SGMII force mode' without in-band negotiation
- which is compatible with 10B/8B encoding of
- PHY_INTERFACE_MODE_1000BASEX with fixed full-duplex and fixed pause.
-- 2.5 times faster clocked 'SGMII force mode' without in-band negotiation
- which is compatible with 10B/8B encoding of
- PHY_INTERFACE_MODE_2500BASEX with fixed full-duplex and fixed pause.
-
-Signed-off-by: Landen Chao <landen.chao@mediatek.com>
-Signed-off-by: Sean Wang <sean.wang@mediatek.com>
----
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -235,6 +235,12 @@ mt7530_write(struct mt7530_priv *priv, u
- }
-
- static u32
-+_mt7530_unlocked_read(struct mt7530_dummy_poll *p)
-+{
-+ return mt7530_mii_read(p->priv, p->reg);
-+}
-+
-+static u32
- _mt7530_read(struct mt7530_dummy_poll *p)
- {
- struct mii_bus *bus = p->priv->bus;
-@@ -482,6 +488,108 @@ mt7530_pad_clk_setup(struct dsa_switch *
- return 0;
- }
-
-+static bool mt7531_dual_sgmii_supported(struct mt7530_priv *priv)
-+{
-+ u32 val;
-+
-+ val = mt7530_read(priv, MT7531_TOP_SIG_SR);
-+
-+ return (val & PAD_DUAL_SGMII_EN) != 0;
-+}
-+
-+static int
-+mt7531_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ u32 val;
-+ u32 top_sig;
-+ u32 hwstrap;
-+ u32 xtal;
-+
-+ if (mt7531_dual_sgmii_supported(priv))
-+ return 0;
-+
-+ val = mt7530_read(priv, MT7531_CREV);
-+ top_sig = mt7530_read(priv, MT7531_TOP_SIG_SR);
-+ hwstrap = mt7530_read(priv, MT7531_HWTRAP);
-+ if ((val & CHIP_REV_M) > 0)
-+ xtal = (top_sig & PAD_MCM_SMI_EN) ? HWTRAP_XTAL_FSEL_40MHZ :
-+ HWTRAP_XTAL_FSEL_25MHZ;
-+ else
-+ xtal = hwstrap & HWTRAP_XTAL_FSEL_MASK;
-+
-+ /* Step 1 : Disable MT7531 COREPLL */
-+ val = mt7530_read(priv, MT7531_PLLGP_EN);
-+ val &= ~EN_COREPLL;
-+ mt7530_write(priv, MT7531_PLLGP_EN, val);
-+
-+ /* Step 2: switch to XTAL output */
-+ val = mt7530_read(priv, MT7531_PLLGP_EN);
-+ val |= SW_CLKSW;
-+ mt7530_write(priv, MT7531_PLLGP_EN, val);
-+
-+ val = mt7530_read(priv, MT7531_PLLGP_CR0);
-+ val &= ~RG_COREPLL_EN;
-+ mt7530_write(priv, MT7531_PLLGP_CR0, val);
-+
-+ /* Step 3: disable PLLGP and enable program PLLGP */
-+ val = mt7530_read(priv, MT7531_PLLGP_EN);
-+ val |= SW_PLLGP;
-+ mt7530_write(priv, MT7531_PLLGP_EN, val);
-+
-+ /* Step 4: program COREPLL output frequency to 500MHz */
-+ val = mt7530_read(priv, MT7531_PLLGP_CR0);
-+ val &= ~RG_COREPLL_POSDIV_M;
-+ val |= 2 << RG_COREPLL_POSDIV_S;
-+ mt7530_write(priv, MT7531_PLLGP_CR0, val);
-+ usleep_range(25, 35);
-+
-+ switch (xtal) {
-+ case HWTRAP_XTAL_FSEL_25MHZ:
-+ val = mt7530_read(priv, MT7531_PLLGP_CR0);
-+ val &= ~RG_COREPLL_SDM_PCW_M;
-+ val |= 0x140000 << RG_COREPLL_SDM_PCW_S;
-+ mt7530_write(priv, MT7531_PLLGP_CR0, val);
-+ break;
-+ case HWTRAP_XTAL_FSEL_40MHZ:
-+ val = mt7530_read(priv, MT7531_PLLGP_CR0);
-+ val &= ~RG_COREPLL_SDM_PCW_M;
-+ val |= 0x190000 << RG_COREPLL_SDM_PCW_S;
-+ mt7530_write(priv, MT7531_PLLGP_CR0, val);
-+ break;
-+ };
-+
-+ /* Set feedback divide ratio update signal to high */
-+ val = mt7530_read(priv, MT7531_PLLGP_CR0);
-+ val |= RG_COREPLL_SDM_PCW_CHG;
-+ mt7530_write(priv, MT7531_PLLGP_CR0, val);
-+ /* Wait for at least 16 XTAL clocks */
-+ usleep_range(10, 20);
-+
-+ /* Step 5: set feedback divide ratio update signal to low */
-+ val = mt7530_read(priv, MT7531_PLLGP_CR0);
-+ val &= ~RG_COREPLL_SDM_PCW_CHG;
-+ mt7530_write(priv, MT7531_PLLGP_CR0, val);
-+
-+ /* Enable 325M clock for SGMII */
-+ mt7530_write(priv, MT7531_ANA_PLLGP_CR5, 0xad0000);
-+
-+ /* Enable 250SSC clock for RGMII */
-+ mt7530_write(priv, MT7531_ANA_PLLGP_CR2, 0x4f40000);
-+
-+ /* Step 6: Enable MT7531 PLL */
-+ val = mt7530_read(priv, MT7531_PLLGP_CR0);
-+ val |= RG_COREPLL_EN;
-+ mt7530_write(priv, MT7531_PLLGP_CR0, val);
-+
-+ val = mt7530_read(priv, MT7531_PLLGP_EN);
-+ val |= EN_COREPLL;
-+ mt7530_write(priv, MT7531_PLLGP_EN, val);
-+ usleep_range(25, 35);
-+
-+ return 0;
-+}
-+
- static void
- mt7530_mib_reset(struct dsa_switch *ds)
- {
-@@ -506,6 +614,217 @@ static int mt7530_phy_write(struct dsa_s
- return mdiobus_write_nested(priv->bus, port, regnum, val);
- }
-
-+static int
-+mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
-+ int regnum)
-+{
-+ struct mii_bus *bus = priv->bus;
-+ struct mt7530_dummy_poll p;
-+ u32 reg, val;
-+ int ret;
-+
-+ INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
-+ !(val & MT7531_PHY_ACS_ST), 20, 100000);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "poll timeout\n");
-+ goto out;
-+ }
-+
-+ reg = MT7531_MDIO_CL45_ADDR | MT7531_MDIO_PHY_ADDR(port) |
-+ MT7531_MDIO_DEV_ADDR(devad) | regnum;
-+ mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
-+
-+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
-+ !(val & MT7531_PHY_ACS_ST), 20, 100000);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "poll timeout\n");
-+ goto out;
-+ }
-+
-+ reg = MT7531_MDIO_CL45_READ | MT7531_MDIO_PHY_ADDR(port) |
-+ MT7531_MDIO_DEV_ADDR(devad);
-+ mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
-+
-+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
-+ !(val & MT7531_PHY_ACS_ST), 20, 100000);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "poll timeout\n");
-+ goto out;
-+ }
-+
-+ ret = val & MT7531_MDIO_RW_DATA_MASK;
-+out:
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return ret;
-+}
-+
-+static int
-+mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
-+ int regnum, u32 data)
-+{
-+ struct mii_bus *bus = priv->bus;
-+ struct mt7530_dummy_poll p;
-+ u32 val, reg;
-+ int ret;
-+
-+ INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
-+ !(val & MT7531_PHY_ACS_ST), 20, 100000);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "poll timeout\n");
-+ goto out;
-+ }
-+
-+ reg = MT7531_MDIO_CL45_ADDR | MT7531_MDIO_PHY_ADDR(port) |
-+ MT7531_MDIO_DEV_ADDR(devad) | regnum;
-+ mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
-+
-+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
-+ !(val & MT7531_PHY_ACS_ST), 20, 100000);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "poll timeout\n");
-+ goto out;
-+ }
-+
-+ reg = MT7531_MDIO_CL45_WRITE | MT7531_MDIO_PHY_ADDR(port) |
-+ MT7531_MDIO_DEV_ADDR(devad) | data;
-+ mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
-+
-+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
-+ !(val & MT7531_PHY_ACS_ST), 20, 100000);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "poll timeout\n");
-+ goto out;
-+ }
-+
-+out:
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return ret;
-+}
-+
-+static int
-+mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
-+{
-+ struct mii_bus *bus = priv->bus;
-+ struct mt7530_dummy_poll p;
-+ int ret;
-+ u32 val;
-+
-+ INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
-+ !(val & MT7531_PHY_ACS_ST), 20, 100000);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "poll timeout\n");
-+ goto out;
-+ }
-+
-+ val = MT7531_MDIO_CL22_READ | MT7531_MDIO_PHY_ADDR(port) |
-+ MT7531_MDIO_REG_ADDR(regnum);
-+
-+ mt7530_mii_write(priv, MT7531_PHY_IAC, val | MT7531_PHY_ACS_ST);
-+
-+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
-+ !(val & MT7531_PHY_ACS_ST), 20, 100000);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "poll timeout\n");
-+ goto out;
-+ }
-+
-+ ret = val & MT7531_MDIO_RW_DATA_MASK;
-+out:
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return ret;
-+}
-+
-+static int
-+mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
-+ u16 data)
-+{
-+ struct mii_bus *bus = priv->bus;
-+ struct mt7530_dummy_poll p;
-+ int ret;
-+ u32 reg;
-+
-+ INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
-+
-+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
-+ !(reg & MT7531_PHY_ACS_ST), 20, 100000);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "poll timeout\n");
-+ goto out;
-+ }
-+
-+ reg = MT7531_MDIO_CL22_WRITE | MT7531_MDIO_PHY_ADDR(port) |
-+ MT7531_MDIO_REG_ADDR(regnum) | data;
-+
-+ mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST);
-+
-+ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
-+ !(reg & MT7531_PHY_ACS_ST), 20, 100000);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "poll timeout\n");
-+ goto out;
-+ }
-+
-+out:
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return ret;
-+}
-+
-+static int
-+mt7531_ind_phy_read(struct dsa_switch *ds, int port, int regnum)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ int devad;
-+ int ret;
-+
-+ if (regnum & MII_ADDR_C45) {
-+ devad = (regnum >> MII_DEVADDR_C45_SHIFT) & 0x1f;
-+ ret = mt7531_ind_c45_phy_read(priv, port, devad,
-+ regnum & MII_REGADDR_C45_MASK);
-+ } else {
-+ ret = mt7531_ind_c22_phy_read(priv, port, regnum);
-+ }
-+
-+ return ret;
-+}
-+
-+static int
-+mt7531_ind_phy_write(struct dsa_switch *ds, int port, int regnum,
-+ u16 data)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ int devad;
-+ int ret;
-+
-+ if (regnum & MII_ADDR_C45) {
-+ devad = (regnum >> MII_DEVADDR_C45_SHIFT) & 0x1f;
-+ ret = mt7531_ind_c45_phy_write(priv, port, devad,
-+ regnum & MII_REGADDR_C45_MASK,
-+ data);
-+ } else {
-+ ret = mt7531_ind_c22_phy_write(priv, port, regnum, data);
-+ }
-+
-+ return ret;
-+}
-+
- static void
- mt7530_get_strings(struct dsa_switch *ds, int port, u32 stringset,
- uint8_t *data)
-@@ -622,9 +941,14 @@ unlock_exit:
- }
-
- static int
--mt7530_cpu_port_enable(struct mt7530_priv *priv,
-- int port)
-+mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
- {
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ /* Setup max capability of CPU port at first */
-+ if (priv->info->cpu_port_config)
-+ priv->info->cpu_port_config(ds, port);
-+
- /* Enable Mediatek header mode on the cpu port */
- mt7530_write(priv, MT7530_PVC_P(port),
- PORT_SPEC_TAG);
-@@ -637,7 +961,7 @@ mt7530_cpu_port_enable(struct mt7530_pri
- mt7530_rmw(priv, MT7530_MFC, CPU_MASK, CPU_EN | CPU_PORT(port));
-
- /* CPU port gets connected to all user ports of
-- * the switch
-+ * the switch.
- */
- mt7530_write(priv, MT7530_PCR_P(port),
- PCR_MATRIX(dsa_user_ports(priv->ds)));
-@@ -1120,27 +1444,42 @@ mt7530_port_vlan_del(struct dsa_switch *
- return 0;
- }
-
--static int mt7530_port_mirror_add(struct dsa_switch *ds, int port,
-+static int mt753x_mirror_port_get(unsigned int id, u32 val)
-+{
-+ return (id == ID_MT7531) ? MT7531_MIRROR_PORT_GET(val) :
-+ MIRROR_PORT(val);
-+}
-+
-+static int mt753x_mirror_port_set(unsigned int id, u32 val)
-+{
-+ return (id == ID_MT7531) ? MT7531_MIRROR_PORT_SET(val) :
-+ MIRROR_PORT(val);
-+}
-+
-+static int mt753x_port_mirror_add(struct dsa_switch *ds, int port,
- struct dsa_mall_mirror_tc_entry *mirror,
- bool ingress)
- {
- struct mt7530_priv *priv = ds->priv;
-+ int monitor_port;
- u32 val;
-
- /* Check for existent entry */
- if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
- return -EEXIST;
-
-- val = mt7530_read(priv, MT7530_MFC);
-+ val = mt7530_read(priv, MT753X_MIRROR_REG(priv->id));
-
- /* MT7530 only supports one monitor port */
-- if (val & MIRROR_EN && MIRROR_PORT(val) != mirror->to_local_port)
-+ monitor_port = mt753x_mirror_port_get(priv->id, val);
-+ if (val & MT753X_MIRROR_EN(priv->id) &&
-+ monitor_port != mirror->to_local_port)
- return -EEXIST;
-
-- val |= MIRROR_EN;
-- val &= ~MIRROR_MASK;
-- val |= mirror->to_local_port;
-- mt7530_write(priv, MT7530_MFC, val);
-+ val |= MT753X_MIRROR_EN(priv->id);
-+ val &= ~MT753X_MIRROR_MASK(priv->id);
-+ val |= mt753x_mirror_port_set(priv->id, mirror->to_local_port);
-+ mt7530_write(priv, MT753X_MIRROR_REG(priv->id), val);
-
- val = mt7530_read(priv, MT7530_PCR_P(port));
- if (ingress) {
-@@ -1155,7 +1494,7 @@ static int mt7530_port_mirror_add(struct
- return 0;
- }
-
--static void mt7530_port_mirror_del(struct dsa_switch *ds, int port,
-+static void mt753x_port_mirror_del(struct dsa_switch *ds, int port,
- struct dsa_mall_mirror_tc_entry *mirror)
- {
- struct mt7530_priv *priv = ds->priv;
-@@ -1172,9 +1511,9 @@ static void mt7530_port_mirror_del(struc
- mt7530_write(priv, MT7530_PCR_P(port), val);
-
- if (!priv->mirror_rx && !priv->mirror_tx) {
-- val = mt7530_read(priv, MT7530_MFC);
-- val &= ~MIRROR_EN;
-- mt7530_write(priv, MT7530_MFC, val);
-+ val = mt7530_read(priv, MT753X_MIRROR_REG(priv->id));
-+ val &= ~MT753X_MIRROR_EN(priv->id);
-+ mt7530_write(priv, MT753X_MIRROR_REG(priv->id), val);
- }
- }
-
-@@ -1280,7 +1619,7 @@ mt7530_setup(struct dsa_switch *ds)
- PCR_MATRIX_CLR);
-
- if (dsa_is_cpu_port(ds, i))
-- mt7530_cpu_port_enable(priv, i);
-+ mt753x_cpu_port_enable(ds, i);
- else
- mt7530_port_disable(ds, i);
-
-@@ -1334,6 +1673,118 @@ mt7530_setup(struct dsa_switch *ds)
- return 0;
- }
-
-+static int
-+mt7531_setup(struct dsa_switch *ds)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ struct mt7530_dummy_poll p;
-+ u32 val, id;
-+ int ret, i;
-+
-+ /* Reset whole chip through gpio pin or memory-mapped registers for
-+ * different type of hardware
-+ */
-+ if (priv->mcm) {
-+ reset_control_assert(priv->rstc);
-+ usleep_range(1000, 1100);
-+ reset_control_deassert(priv->rstc);
-+ } else {
-+ gpiod_set_value_cansleep(priv->reset, 0);
-+ usleep_range(1000, 1100);
-+ gpiod_set_value_cansleep(priv->reset, 1);
-+ }
-+
-+ /* Waiting for MT7530 got to stable */
-+ INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_HWTRAP);
-+ ret = readx_poll_timeout(_mt7530_read, &p, val, val != 0,
-+ 20, 1000000);
-+ if (ret < 0) {
-+ dev_err(priv->dev, "reset timeout\n");
-+ return ret;
-+ }
-+
-+ id = mt7530_read(priv, MT7531_CREV);
-+ id >>= CHIP_NAME_SHIFT;
-+
-+ if (id != MT7531_ID) {
-+ dev_err(priv->dev, "chip %x can't be supported\n", id);
-+ return -ENODEV;
-+ }
-+
-+ /* Reset the switch through internal reset */
-+ mt7530_write(priv, MT7530_SYS_CTRL,
-+ SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
-+ SYS_CTRL_REG_RST);
-+
-+ if (mt7531_dual_sgmii_supported(priv)) {
-+ priv->p5_intf_sel = P5_INTF_SEL_GMAC5_SGMII;
-+
-+ /* Let ds->slave_mii_bus be able to access external phy. */
-+ mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO11_RG_RXD2_MASK,
-+ MT7531_EXT_P_MDC_11);
-+ mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO12_RG_RXD3_MASK,
-+ MT7531_EXT_P_MDIO_12);
-+ } else {
-+ priv->p5_intf_sel = P5_INTF_SEL_GMAC5;
-+ }
-+ dev_dbg(ds->dev, "P5 support %s interface\n",
-+ p5_intf_modes(priv->p5_intf_sel));
-+
-+ mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK,
-+ MT7531_GPIO0_INTERRUPT);
-+
-+ /* Let phylink decide the interface later. */
-+ priv->p5_interface = PHY_INTERFACE_MODE_NA;
-+ priv->p6_interface = PHY_INTERFACE_MODE_NA;
-+
-+ /* Enable PHY core PLL, since phy_device has not yet been created
-+ * provided for phy_[read,write]_mmd_indirect is called, we provide
-+ * our own mt7531_ind_mmd_phy_[read,write] to complete this
-+ * function.
-+ */
-+ val = mt7531_ind_c45_phy_read(priv, MT753X_CTRL_PHY_ADDR,
-+ MDIO_MMD_VEND2, CORE_PLL_GROUP4);
-+ val |= MT7531_PHY_PLL_BYPASS_MODE;
-+ val &= ~MT7531_PHY_PLL_OFF;
-+ mt7531_ind_c45_phy_write(priv, MT753X_CTRL_PHY_ADDR, MDIO_MMD_VEND2,
-+ CORE_PLL_GROUP4, val);
-+
-+ /* BPDU to CPU port */
-+ mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK,
-+ BIT(MT7530_CPU_PORT));
-+ mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK,
-+ MT753X_BPDU_CPU_ONLY);
-+
-+ /* Enable and reset MIB counters */
-+ mt7530_mib_reset(ds);
-+
-+ for (i = 0; i < MT7530_NUM_PORTS; i++) {
-+ /* Disable forwarding by default on all ports */
-+ mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
-+ PCR_MATRIX_CLR);
-+
-+ mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR);
-+
-+ if (dsa_is_cpu_port(ds, i))
-+ mt753x_cpu_port_enable(ds, i);
-+ else
-+ mt7530_port_disable(ds, i);
-+
-+ /* Enable consistent egress tag */
-+ mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
-+ PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
-+ }
-+
-+ ds->configure_vlan_while_not_filtering = true;
-+
-+ /* Flush the FDB table */
-+ ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL);
-+ if (ret < 0)
-+ return ret;
-+
-+ return 0;
-+}
-+
- static bool
- mt7530_phy_mode_supported(struct dsa_switch *ds, int port,
- const struct phylink_link_state *state)
-@@ -1372,6 +1823,47 @@ unsupported:
- return false;
- }
-
-+static bool mt7531_is_rgmii_port(struct mt7530_priv *priv, u32 port)
-+{
-+ return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII);
-+}
-+
-+static bool
-+mt7531_phy_supported(struct dsa_switch *ds, int port,
-+ const struct phylink_link_state *state)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ switch (port) {
-+ case 0: /* Internal phy */
-+ case 1:
-+ case 2:
-+ case 3:
-+ case 4:
-+ if (state->interface != PHY_INTERFACE_MODE_GMII)
-+ goto unsupported;
-+ break;
-+ case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */
-+ if (mt7531_is_rgmii_port(priv, port))
-+ return phy_interface_mode_is_rgmii(state->interface);
-+ fallthrough;
-+ case 6: /* 1st cpu port supports sgmii/8023z only */
-+ if (state->interface != PHY_INTERFACE_MODE_SGMII &&
-+ !phy_interface_mode_is_8023z(state->interface))
-+ goto unsupported;
-+ break;
-+ default:
-+ dev_err(priv->dev, "%s: unsupported port: %i\n", __func__,
-+ port);
-+ goto unsupported;
-+ }
-+
-+ return true;
-+
-+unsupported:
-+ return false;
-+}
-+
- static bool
- mt753x_phy_mode_supported(struct dsa_switch *ds, int port,
- const struct phylink_link_state *state)
-@@ -1404,6 +1896,227 @@ mt7530_mac_config(struct dsa_switch *ds,
- return 0;
- }
-
-+static int mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port,
-+ phy_interface_t interface,
-+ struct phy_device *phydev)
-+{
-+ u32 val;
-+
-+ if (!mt7531_is_rgmii_port(priv, port)) {
-+ dev_err(priv->dev, "RGMII mode is not available for port %d\n",
-+ port);
-+ return -EINVAL;
-+ }
-+
-+ val = mt7530_read(priv, MT7531_CLKGEN_CTRL);
-+ val |= GP_CLK_EN;
-+ val &= ~GP_MODE_MASK;
-+ val |= GP_MODE(MT7531_GP_MODE_RGMII);
-+ val &= ~CLK_SKEW_IN_MASK;
-+ val |= CLK_SKEW_IN(MT7531_CLK_SKEW_NO_CHG);
-+ val &= ~CLK_SKEW_OUT_MASK;
-+ val |= CLK_SKEW_OUT(MT7531_CLK_SKEW_NO_CHG);
-+ val |= TXCLK_NO_REVERSE | RXCLK_NO_DELAY;
-+
-+ /* Do not adjust rgmii delay when vendor phy driver presents. */
-+ if (!phydev || phy_driver_is_genphy(phydev)) {
-+ val &= ~(TXCLK_NO_REVERSE | RXCLK_NO_DELAY);
-+ switch (interface) {
-+ case PHY_INTERFACE_MODE_RGMII:
-+ val |= TXCLK_NO_REVERSE;
-+ val |= RXCLK_NO_DELAY;
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ val |= TXCLK_NO_REVERSE;
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ val |= RXCLK_NO_DELAY;
-+ break;
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ }
-+ mt7530_write(priv, MT7531_CLKGEN_CTRL, val);
-+
-+ return 0;
-+}
-+
-+static void mt7531_sgmii_validate(struct mt7530_priv *priv, int port,
-+ unsigned long *supported)
-+{
-+ /* Port5 supports ethier RGMII or SGMII.
-+ * Port6 supports SGMII only.
-+ */
-+ switch (port) {
-+ case 5:
-+ if (mt7531_is_rgmii_port(priv, port))
-+ break;
-+ fallthrough;
-+ case 6:
-+ phylink_set(supported, 1000baseX_Full);
-+ phylink_set(supported, 2500baseX_Full);
-+ phylink_set(supported, 2500baseT_Full);
-+ }
-+}
-+
-+static void
-+mt7531_sgmii_link_up_force(struct dsa_switch *ds, int port,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ unsigned int val;
-+
-+ /* For adjusting speed and duplex of SGMII force mode. */
-+ if (interface != PHY_INTERFACE_MODE_SGMII ||
-+ phylink_autoneg_inband(mode))
-+ return;
-+
-+ /* SGMII force mode setting */
-+ val = mt7530_read(priv, MT7531_SGMII_MODE(port));
-+ val &= ~MT7531_SGMII_IF_MODE_MASK;
-+
-+ switch (speed) {
-+ case SPEED_10:
-+ val |= MT7531_SGMII_FORCE_SPEED_10;
-+ break;
-+ case SPEED_100:
-+ val |= MT7531_SGMII_FORCE_SPEED_100;
-+ break;
-+ case SPEED_1000:
-+ val |= MT7531_SGMII_FORCE_SPEED_1000;
-+ break;
-+ }
-+
-+ /* MT7531 SGMII 1G force mode can only work in full duplex mode,
-+ * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
-+ */
-+ if ((speed == SPEED_10 || speed == SPEED_100) &&
-+ duplex != DUPLEX_FULL)
-+ val |= MT7531_SGMII_FORCE_HALF_DUPLEX;
-+
-+ mt7530_write(priv, MT7531_SGMII_MODE(port), val);
-+}
-+
-+static bool mt753x_is_mac_port(u32 port)
-+{
-+ return (port == 5 || port == 6);
-+}
-+
-+static int mt7531_sgmii_setup_mode_force(struct mt7530_priv *priv, u32 port,
-+ phy_interface_t interface)
-+{
-+ u32 val;
-+
-+ if (!mt753x_is_mac_port(port))
-+ return -EINVAL;
-+
-+ mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port),
-+ MT7531_SGMII_PHYA_PWD);
-+
-+ val = mt7530_read(priv, MT7531_PHYA_CTRL_SIGNAL3(port));
-+ val &= ~MT7531_RG_TPHY_SPEED_MASK;
-+ /* Setup 2.5 times faster clock for 2.5Gbps data speeds with 10B/8B
-+ * encoding.
-+ */
-+ val |= (interface == PHY_INTERFACE_MODE_2500BASEX) ?
-+ MT7531_RG_TPHY_SPEED_3_125G : MT7531_RG_TPHY_SPEED_1_25G;
-+ mt7530_write(priv, MT7531_PHYA_CTRL_SIGNAL3(port), val);
-+
-+ mt7530_clear(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE);
-+
-+ /* MT7531 SGMII 1G and 2.5G force mode can only work in full duplex
-+ * mode, no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
-+ */
-+ mt7530_rmw(priv, MT7531_SGMII_MODE(port),
-+ MT7531_SGMII_IF_MODE_MASK | MT7531_SGMII_REMOTE_FAULT_DIS,
-+ MT7531_SGMII_FORCE_SPEED_1000);
-+
-+ mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0);
-+
-+ return 0;
-+}
-+
-+static int mt7531_sgmii_setup_mode_an(struct mt7530_priv *priv, int port,
-+ phy_interface_t interface)
-+{
-+ if (!mt753x_is_mac_port(port))
-+ return -EINVAL;
-+
-+ mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port),
-+ MT7531_SGMII_PHYA_PWD);
-+
-+ mt7530_rmw(priv, MT7531_PHYA_CTRL_SIGNAL3(port),
-+ MT7531_RG_TPHY_SPEED_MASK, MT7531_RG_TPHY_SPEED_1_25G);
-+
-+ mt7530_set(priv, MT7531_SGMII_MODE(port),
-+ MT7531_SGMII_REMOTE_FAULT_DIS |
-+ MT7531_SGMII_SPEED_DUPLEX_AN);
-+
-+ mt7530_rmw(priv, MT7531_PCS_SPEED_ABILITY(port),
-+ MT7531_SGMII_TX_CONFIG_MASK, 1);
-+
-+ mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE);
-+
-+ mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_RESTART);
-+
-+ mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0);
-+
-+ return 0;
-+}
-+
-+static void mt7531_sgmii_restart_an(struct dsa_switch *ds, int port)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ u32 val;
-+
-+ /* Only restart AN when AN is enabled */
-+ val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
-+ if (val & MT7531_SGMII_AN_ENABLE) {
-+ val |= MT7531_SGMII_AN_RESTART;
-+ mt7530_write(priv, MT7531_PCS_CONTROL_1(port), val);
-+ }
-+}
-+
-+static int
-+mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-+ phy_interface_t interface)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ struct phy_device *phydev;
-+ const struct dsa_port *dp;
-+
-+ if (!mt753x_is_mac_port(port)) {
-+ dev_err(priv->dev, "port %d is not a MAC port\n", port);
-+ return -EINVAL;
-+ }
-+
-+ switch (interface) {
-+ case PHY_INTERFACE_MODE_RGMII:
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ dp = dsa_to_port(ds, port);
-+ phydev = dp->slave->phydev;
-+ return mt7531_rgmii_setup(priv, port, interface, phydev);
-+ case PHY_INTERFACE_MODE_SGMII:
-+ return mt7531_sgmii_setup_mode_an(priv, port, interface);
-+ case PHY_INTERFACE_MODE_NA:
-+ case PHY_INTERFACE_MODE_1000BASEX:
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ if (phylink_autoneg_inband(mode))
-+ return -EINVAL;
-+
-+ return mt7531_sgmii_setup_mode_force(priv, port, interface);
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return -EINVAL;
-+}
-+
- static int
- mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
- const struct phylink_link_state *state)
-@@ -1439,6 +2152,8 @@ mt753x_phylink_mac_config(struct dsa_swi
- if (mt753x_mac_config(ds, port, mode, state) < 0)
- goto unsupported;
-
-+ if (priv->p5_intf_sel != P5_DISABLED)
-+ priv->p5_interface = state->interface;
- break;
- case 6: /* 1st cpu port */
- if (priv->p6_interface == state->interface)
-@@ -1458,7 +2173,8 @@ unsupported:
- return;
- }
-
-- if (phylink_autoneg_inband(mode)) {
-+ if (phylink_autoneg_inband(mode) &&
-+ state->interface != PHY_INTERFACE_MODE_SGMII) {
- dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
- __func__);
- return;
-@@ -1468,7 +2184,7 @@ unsupported:
- mcr_new = mcr_cur;
- mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
- mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN |
-- PMCR_BACKPR_EN | PMCR_FORCE_MODE;
-+ PMCR_BACKPR_EN | PMCR_FORCE_MODE_ID(priv->id);
-
- /* Are we connected to external phy */
- if (port == 5 && dsa_is_user_port(ds, 5))
-@@ -1478,7 +2194,18 @@ unsupported:
- mt7530_write(priv, MT7530_PMCR_P(port), mcr_new);
- }
-
--static void mt7530_phylink_mac_link_down(struct dsa_switch *ds, int port,
-+static void
-+mt753x_phylink_mac_an_restart(struct dsa_switch *ds, int port)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ if (!priv->info->mac_pcs_an_restart)
-+ return;
-+
-+ priv->info->mac_pcs_an_restart(ds, port);
-+}
-+
-+static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface)
- {
-@@ -1487,7 +2214,19 @@ static void mt7530_phylink_mac_link_down
- mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
- }
-
--static void mt7530_phylink_mac_link_up(struct dsa_switch *ds, int port,
-+static void mt753x_mac_pcs_link_up(struct dsa_switch *ds, int port,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ if (!priv->info->mac_pcs_link_up)
-+ return;
-+
-+ priv->info->mac_pcs_link_up(ds, port, mode, interface, speed, duplex);
-+}
-+
-+static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface,
- struct phy_device *phydev,
-@@ -1497,18 +2236,29 @@ static void mt7530_phylink_mac_link_up(s
- struct mt7530_priv *priv = ds->priv;
- u32 mcr;
-
-+ mt753x_mac_pcs_link_up(ds, port, mode, interface, speed, duplex);
-+
- mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
-
-+ /* MT753x MAC works in 1G full duplex mode for all up-clocked
-+ * variants.
-+ */
-+ if (interface == PHY_INTERFACE_MODE_TRGMII ||
-+ (phy_interface_mode_is_8023z(interface))) {
-+ speed = SPEED_1000;
-+ duplex = DUPLEX_FULL;
-+ }
-+
- switch (speed) {
- case SPEED_1000:
- mcr |= PMCR_FORCE_SPEED_1000;
- if (priv->eee_enable & BIT(port))
-- mcr_new |= PMCR_FORCE_EEE1G;
-+ mcr |= PMCR_FORCE_EEE1G;
- break;
- case SPEED_100:
- mcr |= PMCR_FORCE_SPEED_100;
- if (priv->eee_enable & BIT(port))
-- mcr_new |= PMCR_FORCE_EEE100;
-+ mcr |= PMCR_FORCE_EEE100;
- break;
- }
- if (duplex == DUPLEX_FULL) {
-@@ -1522,6 +2272,45 @@ static void mt7530_phylink_mac_link_up(s
- mt7530_set(priv, MT7530_PMCR_P(port), mcr);
- }
-
-+static int
-+mt7531_cpu_port_config(struct dsa_switch *ds, int port)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+ phy_interface_t interface;
-+ int speed;
-+
-+ switch (port) {
-+ case 5:
-+ if (mt7531_is_rgmii_port(priv, port))
-+ interface = PHY_INTERFACE_MODE_RGMII;
-+ else
-+ interface = PHY_INTERFACE_MODE_2500BASEX;
-+
-+ priv->p5_interface = interface;
-+ break;
-+ case 6:
-+ interface = PHY_INTERFACE_MODE_2500BASEX;
-+
-+ mt7531_pad_setup(ds, interface);
-+
-+ priv->p6_interface = interface;
-+ break;
-+ };
-+
-+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
-+ speed = SPEED_2500;
-+ else
-+ speed = SPEED_1000;
-+
-+ mt7531_mac_config(ds, port, MLO_AN_FIXED, interface);
-+ mt7530_write(priv, MT7530_PMCR_P(port),
-+ PMCR_CPU_PORT_SETTING(priv->id));
-+ mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
-+ speed, DUPLEX_FULL, true, true);
-+
-+ return 0;
-+}
-+
- static void
- mt7530_mac_port_validate(struct dsa_switch *ds, int port,
- unsigned long *supported)
-@@ -1530,6 +2319,14 @@ mt7530_mac_port_validate(struct dsa_swit
- phylink_set(supported, 1000baseX_Full);
- }
-
-+static void mt7531_mac_port_validate(struct dsa_switch *ds, int port,
-+ unsigned long *supported)
-+{
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ mt7531_sgmii_validate(priv, port, supported);
-+}
-+
- static void
- mt753x_phylink_validate(struct dsa_switch *ds, int port,
- unsigned long *supported,
-@@ -1546,7 +2343,8 @@ mt753x_phylink_validate(struct dsa_switc
-
- phylink_set_port_modes(mask);
-
-- if (state->interface != PHY_INTERFACE_MODE_TRGMII) {
-+ if (state->interface != PHY_INTERFACE_MODE_TRGMII ||
-+ !phy_interface_mode_is_8023z(state->interface)) {
- phylink_set(mask, 10baseT_Half);
- phylink_set(mask, 10baseT_Full);
- phylink_set(mask, 100baseT_Half);
-@@ -1565,6 +2363,11 @@ mt753x_phylink_validate(struct dsa_switc
-
- linkmode_and(supported, supported, mask);
- linkmode_and(state->advertising, state->advertising, mask);
-+
-+ /* We can only operate at 2500BaseX or 1000BaseX. If requested
-+ * to advertise both, only report advertising at 2500BaseX.
-+ */
-+ phylink_helper_basex_speed(state);
- }
-
- static int
-@@ -1655,6 +2458,63 @@ static int mt7530_set_mac_eee(struct dsa
- return 0;
- }
-
-+#ifdef notyet
-+static int
-+mt7531_sgmii_pcs_get_state_an(struct mt7530_priv *priv, int port,
-+ struct phylink_link_state *state)
-+{
-+ u32 status, val;
-+ u16 config_reg;
-+
-+ status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
-+ state->link = !!(status & MT7531_SGMII_LINK_STATUS);
-+ if (state->interface == PHY_INTERFACE_MODE_SGMII &&
-+ (status & MT7531_SGMII_AN_ENABLE)) {
-+ val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port));
-+ config_reg = val >> 16;
-+
-+ switch (config_reg & LPA_SGMII_SPD_MASK) {
-+ case LPA_SGMII_1000:
-+ state->speed = SPEED_1000;
-+ break;
-+ case LPA_SGMII_100:
-+ state->speed = SPEED_100;
-+ break;
-+ case LPA_SGMII_10:
-+ state->speed = SPEED_10;
-+ break;
-+ default:
-+ dev_err(priv->dev, "invalid sgmii PHY speed\n");
-+ state->link = false;
-+ return -EINVAL;
-+ }
-+
-+ if (config_reg & LPA_SGMII_FULL_DUPLEX)
-+ state->duplex = DUPLEX_FULL;
-+ else
-+ state->duplex = DUPLEX_HALF;
-+ }
-+
-+ return 0;
-+}
-+#endif
-+
-+static int
-+mt7531_phylink_mac_link_state(struct dsa_switch *ds, int port,
-+ struct phylink_link_state *state)
-+{
-+#ifdef notyet
-+ struct mt7530_priv *priv = ds->priv;
-+
-+ if (state->interface == PHY_INTERFACE_MODE_SGMII)
-+ return mt7531_sgmii_pcs_get_state_an(priv, port, state);
-+#else
-+ return mt7530_phylink_mac_link_state(ds, port, state);
-+#endif
-+
-+ return -EOPNOTSUPP;
-+}
-+
- static int
- mt753x_phylink_mac_link_state(struct dsa_switch *ds, int port,
- struct phylink_link_state *state)
-@@ -1708,13 +2568,14 @@ static const struct dsa_switch_ops mt753
- .port_vlan_prepare = mt7530_port_vlan_prepare,
- .port_vlan_add = mt7530_port_vlan_add,
- .port_vlan_del = mt7530_port_vlan_del,
-- .port_mirror_add = mt7530_port_mirror_add,
-- .port_mirror_del = mt7530_port_mirror_del,
-+ .port_mirror_add = mt753x_port_mirror_add,
-+ .port_mirror_del = mt753x_port_mirror_del,
- .phylink_validate = mt753x_phylink_validate,
- .phylink_mac_link_state = mt753x_phylink_mac_link_state,
- .phylink_mac_config = mt753x_phylink_mac_config,
-- .phylink_mac_link_down = mt7530_phylink_mac_link_down,
-- .phylink_mac_link_up = mt7530_phylink_mac_link_up,
-+ .phylink_mac_an_restart = mt753x_phylink_mac_an_restart,
-+ .phylink_mac_link_down = mt753x_phylink_mac_link_down,
-+ .phylink_mac_link_up = mt753x_phylink_mac_link_up,
- .get_mac_eee = mt7530_get_mac_eee,
- .set_mac_eee = mt7530_set_mac_eee,
- };
-@@ -1742,11 +2603,26 @@ static const struct mt753x_info mt753x_t
- .mac_port_get_state = mt7530_phylink_mac_link_state,
- .mac_port_config = mt7530_mac_config,
- },
-+ [ID_MT7531] = {
-+ .id = ID_MT7531,
-+ .sw_setup = mt7531_setup,
-+ .phy_read = mt7531_ind_phy_read,
-+ .phy_write = mt7531_ind_phy_write,
-+ .pad_setup = mt7531_pad_setup,
-+ .cpu_port_config = mt7531_cpu_port_config,
-+ .phy_mode_supported = mt7531_phy_supported,
-+ .mac_port_validate = mt7531_mac_port_validate,
-+ .mac_port_get_state = mt7531_phylink_mac_link_state,
-+ .mac_port_config = mt7531_mac_config,
-+ .mac_pcs_an_restart = mt7531_sgmii_restart_an,
-+ .mac_pcs_link_up = mt7531_sgmii_link_up_force,
-+ },
- };
-
- static const struct of_device_id mt7530_of_match[] = {
- { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
- { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
-+ { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
- { /* sentinel */ },
- };
- MODULE_DEVICE_TABLE(of, mt7530_of_match);
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -14,6 +14,7 @@
- enum mt753x_id {
- ID_MT7530 = 0,
- ID_MT7621 = 1,
-+ ID_MT7531 = 2,
- };
-
- #define NUM_TRGMII_CTRL 5
-@@ -41,6 +42,33 @@ enum mt753x_id {
- #define MIRROR_PORT(x) ((x) & 0x7)
- #define MIRROR_MASK 0x7
-
-+/* Registers for CPU forward control */
-+#define MT7531_CFC 0x4
-+#define MT7531_MIRROR_EN BIT(19)
-+#define MT7531_MIRROR_MASK (MIRROR_MASK << 16)
-+#define MT7531_MIRROR_PORT_GET(x) (((x) >> 16) & MIRROR_MASK)
-+#define MT7531_MIRROR_PORT_SET(x) (((x) & MIRROR_MASK) << 16)
-+#define MT7531_CPU_PMAP_MASK GENMASK(7, 0)
-+
-+#define MT753X_MIRROR_REG(id) (((id) == ID_MT7531) ? \
-+ MT7531_CFC : MT7530_MFC)
-+#define MT753X_MIRROR_EN(id) (((id) == ID_MT7531) ? \
-+ MT7531_MIRROR_EN : MIRROR_EN)
-+#define MT753X_MIRROR_MASK(id) (((id) == ID_MT7531) ? \
-+ MT7531_MIRROR_MASK : MIRROR_MASK)
-+
-+/* Registers for BPDU and PAE frame control*/
-+#define MT753X_BPC 0x24
-+#define MT753X_BPDU_PORT_FW_MASK GENMASK(2, 0)
-+
-+enum mt753x_bpdu_port_fw {
-+ MT753X_BPDU_FOLLOW_MFC,
-+ MT753X_BPDU_CPU_EXCLUDE = 4,
-+ MT753X_BPDU_CPU_INCLUDE = 5,
-+ MT753X_BPDU_CPU_ONLY = 6,
-+ MT753X_BPDU_DROP = 7,
-+};
-+
- /* Registers for address table access */
- #define MT7530_ATA1 0x74
- #define STATIC_EMP 0
-@@ -222,10 +250,30 @@ enum mt7530_vlan_port_attr {
- #define PMCR_FORCE_LNK BIT(0)
- #define PMCR_SPEED_MASK (PMCR_FORCE_SPEED_100 | \
- PMCR_FORCE_SPEED_1000)
-+#define MT7531_FORCE_LNK BIT(31)
-+#define MT7531_FORCE_SPD BIT(30)
-+#define MT7531_FORCE_DPX BIT(29)
-+#define MT7531_FORCE_RX_FC BIT(28)
-+#define MT7531_FORCE_TX_FC BIT(27)
-+#define MT7531_FORCE_MODE (MT7531_FORCE_LNK | \
-+ MT7531_FORCE_SPD | \
-+ MT7531_FORCE_DPX | \
-+ MT7531_FORCE_RX_FC | \
-+ MT7531_FORCE_TX_FC)
-+#define PMCR_FORCE_MODE_ID(id) (((id) == ID_MT7531) ? \
-+ MT7531_FORCE_MODE : \
-+ PMCR_FORCE_MODE)
- #define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
- PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
- PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
- PMCR_FORCE_FDX | PMCR_FORCE_LNK)
-+#define PMCR_CPU_PORT_SETTING(id) (PMCR_FORCE_MODE_ID((id)) | \
-+ PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | \
-+ PMCR_BACKOFF_EN | PMCR_BACKPR_EN | \
-+ PMCR_TX_EN | PMCR_RX_EN | \
-+ PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
-+ PMCR_FORCE_SPEED_1000 | \
-+ PMCR_FORCE_FDX | PMCR_FORCE_LNK)
-
- #define MT7530_PMSR_P(x) (0x3008 + (x) * 0x100)
- #define PMSR_EEE1G BIT(7)
-@@ -245,6 +293,10 @@ enum mt7530_vlan_port_attr {
- #define LPI_THRESH(x) ((x & 0xFFF) << 4)
- #define LPI_MODE_EN BIT(0)
-
-+/* Register for port debug count */
-+#define MT7531_DBG_CNT(x) (0x3018 + (x) * 0x100)
-+#define MT7531_DIS_CLR BIT(31)
-+
- /* Register for MIB */
- #define MT7530_PORT_MIB_COUNTER(x) (0x4000 + (x) * 0x100)
- #define MT7530_MIB_CCR 0x4fe0
-@@ -262,12 +314,118 @@ enum mt7530_vlan_port_attr {
- CCR_RX_OCT_CNT_BAD | \
- CCR_TX_OCT_CNT_GOOD | \
- CCR_TX_OCT_CNT_BAD)
-+
-+/* MT7531 SGMII register group */
-+#define MT7531_SGMII_REG_BASE 0x5000
-+#define MT7531_SGMII_REG(p, r) (MT7531_SGMII_REG_BASE + \
-+ ((p) - 5) * 0x1000 + (r))
-+
-+/* Register forSGMII PCS_CONTROL_1 */
-+#define MT7531_PCS_CONTROL_1(p) MT7531_SGMII_REG(p, 0x00)
-+#define MT7531_SGMII_LINK_STATUS BIT(18)
-+#define MT7531_SGMII_AN_ENABLE BIT(12)
-+#define MT7531_SGMII_AN_RESTART BIT(9)
-+
-+/* Register for SGMII PCS_SPPED_ABILITY */
-+#define MT7531_PCS_SPEED_ABILITY(p) MT7531_SGMII_REG(p, 0x08)
-+#define MT7531_SGMII_TX_CONFIG_MASK GENMASK(15, 0)
-+#define MT7531_SGMII_TX_CONFIG BIT(0)
-+
-+/* Register for SGMII_MODE */
-+#define MT7531_SGMII_MODE(p) MT7531_SGMII_REG(p, 0x20)
-+#define MT7531_SGMII_REMOTE_FAULT_DIS BIT(8)
-+#define MT7531_SGMII_IF_MODE_MASK GENMASK(5, 1)
-+#define MT7531_SGMII_FORCE_DUPLEX BIT(4)
-+#define MT7531_SGMII_FORCE_SPEED_MASK GENMASK(3, 2)
-+#define MT7531_SGMII_FORCE_SPEED_1000 BIT(3)
-+#define MT7531_SGMII_FORCE_SPEED_100 BIT(2)
-+#define MT7531_SGMII_FORCE_SPEED_10 0
-+#define MT7531_SGMII_SPEED_DUPLEX_AN BIT(1)
-+
-+enum mt7531_sgmii_force_duplex {
-+ MT7531_SGMII_FORCE_FULL_DUPLEX = 0,
-+ MT7531_SGMII_FORCE_HALF_DUPLEX = 0x10,
-+};
-+
-+/* Fields of QPHY_PWR_STATE_CTRL */
-+#define MT7531_QPHY_PWR_STATE_CTRL(p) MT7531_SGMII_REG(p, 0xe8)
-+#define MT7531_SGMII_PHYA_PWD BIT(4)
-+
-+/* Values of SGMII SPEED */
-+#define MT7531_PHYA_CTRL_SIGNAL3(p) MT7531_SGMII_REG(p, 0x128)
-+#define MT7531_RG_TPHY_SPEED_MASK (BIT(2) | BIT(3))
-+#define MT7531_RG_TPHY_SPEED_1_25G 0x0
-+#define MT7531_RG_TPHY_SPEED_3_125G BIT(2)
-+
- /* Register for system reset */
- #define MT7530_SYS_CTRL 0x7000
- #define SYS_CTRL_PHY_RST BIT(2)
- #define SYS_CTRL_SW_RST BIT(1)
- #define SYS_CTRL_REG_RST BIT(0)
-
-+/* Register for PHY Indirect Access Control */
-+#define MT7531_PHY_IAC 0x701C
-+#define MT7531_PHY_ACS_ST BIT(31)
-+#define MT7531_MDIO_REG_ADDR_MASK (0x1f << 25)
-+#define MT7531_MDIO_PHY_ADDR_MASK (0x1f << 20)
-+#define MT7531_MDIO_CMD_MASK (0x3 << 18)
-+#define MT7531_MDIO_ST_MASK (0x3 << 16)
-+#define MT7531_MDIO_RW_DATA_MASK (0xffff)
-+#define MT7531_MDIO_REG_ADDR(x) (((x) & 0x1f) << 25)
-+#define MT7531_MDIO_DEV_ADDR(x) (((x) & 0x1f) << 25)
-+#define MT7531_MDIO_PHY_ADDR(x) (((x) & 0x1f) << 20)
-+#define MT7531_MDIO_CMD(x) (((x) & 0x3) << 18)
-+#define MT7531_MDIO_ST(x) (((x) & 0x3) << 16)
-+
-+enum mt7531_phy_iac_cmd {
-+ MT7531_MDIO_ADDR = 0,
-+ MT7531_MDIO_WRITE = 1,
-+ MT7531_MDIO_READ = 2,
-+ MT7531_MDIO_READ_CL45 = 3,
-+};
-+
-+/* MDIO_ST: MDIO start field */
-+enum mt7531_mdio_st {
-+ MT7531_MDIO_ST_CL45 = 0,
-+ MT7531_MDIO_ST_CL22 = 1,
-+};
-+
-+#define MT7531_MDIO_CL22_READ (MT7531_MDIO_ST(MT7531_MDIO_ST_CL22) | \
-+ MT7531_MDIO_CMD(MT7531_MDIO_READ))
-+#define MT7531_MDIO_CL22_WRITE (MT7531_MDIO_ST(MT7531_MDIO_ST_CL22) | \
-+ MT7531_MDIO_CMD(MT7531_MDIO_WRITE))
-+#define MT7531_MDIO_CL45_ADDR (MT7531_MDIO_ST(MT7531_MDIO_ST_CL45) | \
-+ MT7531_MDIO_CMD(MT7531_MDIO_ADDR))
-+#define MT7531_MDIO_CL45_READ (MT7531_MDIO_ST(MT7531_MDIO_ST_CL45) | \
-+ MT7531_MDIO_CMD(MT7531_MDIO_READ))
-+#define MT7531_MDIO_CL45_WRITE (MT7531_MDIO_ST(MT7531_MDIO_ST_CL45) | \
-+ MT7531_MDIO_CMD(MT7531_MDIO_WRITE))
-+
-+/* Register for RGMII clock phase */
-+#define MT7531_CLKGEN_CTRL 0x7500
-+#define CLK_SKEW_OUT(x) (((x) & 0x3) << 8)
-+#define CLK_SKEW_OUT_MASK GENMASK(9, 8)
-+#define CLK_SKEW_IN(x) (((x) & 0x3) << 6)
-+#define CLK_SKEW_IN_MASK GENMASK(7, 6)
-+#define RXCLK_NO_DELAY BIT(5)
-+#define TXCLK_NO_REVERSE BIT(4)
-+#define GP_MODE(x) (((x) & 0x3) << 1)
-+#define GP_MODE_MASK GENMASK(2, 1)
-+#define GP_CLK_EN BIT(0)
-+
-+enum mt7531_gp_mode {
-+ MT7531_GP_MODE_RGMII = 0,
-+ MT7531_GP_MODE_MII = 1,
-+ MT7531_GP_MODE_REV_MII = 2
-+};
-+
-+enum mt7531_clk_skew {
-+ MT7531_CLK_SKEW_NO_CHG = 0,
-+ MT7531_CLK_SKEW_DLY_100PPS = 1,
-+ MT7531_CLK_SKEW_DLY_200PPS = 2,
-+ MT7531_CLK_SKEW_REVERSE = 3,
-+};
-+
- /* Register for hw trap status */
- #define MT7530_HWTRAP 0x7800
- #define HWTRAP_XTAL_MASK (BIT(10) | BIT(9))
-@@ -275,6 +433,16 @@ enum mt7530_vlan_port_attr {
- #define HWTRAP_XTAL_40MHZ (BIT(10))
- #define HWTRAP_XTAL_20MHZ (BIT(9))
-
-+#define MT7531_HWTRAP 0x7800
-+#define HWTRAP_XTAL_FSEL_MASK BIT(7)
-+#define HWTRAP_XTAL_FSEL_25MHZ BIT(7)
-+#define HWTRAP_XTAL_FSEL_40MHZ 0
-+/* Unique fields of (M)HWSTRAP for MT7531 */
-+#define XTAL_FSEL_S 7
-+#define XTAL_FSEL_M BIT(7)
-+#define PHY_EN BIT(6)
-+#define CHG_STRAP BIT(8)
-+
- /* Register for hw trap modification */
- #define MT7530_MHWTRAP 0x7804
- #define MHWTRAP_PHY0_SEL BIT(20)
-@@ -289,14 +457,37 @@ enum mt7530_vlan_port_attr {
- #define MT7530_TOP_SIG_CTRL 0x7808
- #define TOP_SIG_CTRL_NORMAL (BIT(17) | BIT(16))
-
-+#define MT7531_TOP_SIG_SR 0x780c
-+#define PAD_DUAL_SGMII_EN BIT(1)
-+#define PAD_MCM_SMI_EN BIT(0)
-+
- #define MT7530_IO_DRV_CR 0x7810
- #define P5_IO_CLK_DRV(x) ((x) & 0x3)
- #define P5_IO_DATA_DRV(x) (((x) & 0x3) << 4)
-
-+#define MT7531_CHIP_REV 0x781C
-+
-+#define MT7531_PLLGP_EN 0x7820
-+#define EN_COREPLL BIT(2)
-+#define SW_CLKSW BIT(1)
-+#define SW_PLLGP BIT(0)
-+
- #define MT7530_P6ECR 0x7830
- #define P6_INTF_MODE_MASK 0x3
- #define P6_INTF_MODE(x) ((x) & 0x3)
-
-+#define MT7531_PLLGP_CR0 0x78a8
-+#define RG_COREPLL_EN BIT(22)
-+#define RG_COREPLL_POSDIV_S 23
-+#define RG_COREPLL_POSDIV_M 0x3800000
-+#define RG_COREPLL_SDM_PCW_S 1
-+#define RG_COREPLL_SDM_PCW_M 0x3ffffe
-+#define RG_COREPLL_SDM_PCW_CHG BIT(0)
-+
-+/* Registers for RGMII and SGMII PLL clock */
-+#define MT7531_ANA_PLLGP_CR2 0x78b0
-+#define MT7531_ANA_PLLGP_CR5 0x78bc
-+
- /* Registers for TRGMII on the both side */
- #define MT7530_TRGMII_RCK_CTRL 0x7a00
- #define RX_RST BIT(31)
-@@ -335,10 +526,25 @@ enum mt7530_vlan_port_attr {
- #define MT7530_P5RGMIITXCR 0x7b04
- #define CSR_RGMII_TXC_CFG(x) ((x) & 0x1f)
-
-+/* Registers for GPIO mode */
-+#define MT7531_GPIO_MODE0 0x7c0c
-+#define MT7531_GPIO0_MASK GENMASK(3, 0)
-+#define MT7531_GPIO0_INTERRUPT 1
-+
-+#define MT7531_GPIO_MODE1 0x7c10
-+#define MT7531_GPIO11_RG_RXD2_MASK GENMASK(15, 12)
-+#define MT7531_EXT_P_MDC_11 (2 << 12)
-+#define MT7531_GPIO12_RG_RXD3_MASK GENMASK(19, 16)
-+#define MT7531_EXT_P_MDIO_12 (2 << 16)
-+
- #define MT7530_CREV 0x7ffc
- #define CHIP_NAME_SHIFT 16
- #define MT7530_ID 0x7530
-
-+#define MT7531_CREV 0x781C
-+#define CHIP_REV_M 0x0f
-+#define MT7531_ID 0x7531
-+
- /* Registers for core PLL access through mmd indirect */
- #define CORE_PLL_GROUP2 0x401
- #define RG_SYSPLL_EN_NORMAL BIT(15)
-@@ -355,6 +561,10 @@ enum mt7530_vlan_port_attr {
- #define RG_SYSPLL_DDSFBK_EN BIT(12)
- #define RG_SYSPLL_BIAS_EN BIT(11)
- #define RG_SYSPLL_BIAS_LPF_EN BIT(10)
-+#define MT7531_PHY_PLL_OFF BIT(5)
-+#define MT7531_PHY_PLL_BYPASS_MODE BIT(4)
-+
-+#define MT753X_CTRL_PHY_ADDR 0
-
- #define CORE_PLL_GROUP5 0x404
- #define RG_LCDDS_PCW_NCPO1(x) ((x) & 0xffff)
-@@ -433,6 +643,7 @@ enum p5_interface_select {
- P5_INTF_SEL_PHY_P0,
- P5_INTF_SEL_PHY_P4,
- P5_INTF_SEL_GMAC5,
-+ P5_INTF_SEL_GMAC5_SGMII,
- };
-
- static const char *p5_intf_modes(unsigned int p5_interface)
-@@ -446,6 +657,8 @@ static const char *p5_intf_modes(unsigne
- return "PHY P4";
- case P5_INTF_SEL_GMAC5:
- return "GMAC5";
-+ case P5_INTF_SEL_GMAC5_SGMII:
-+ return "GMAC5_SGMII";
- default:
- return "unknown";
- }
-@@ -466,6 +679,10 @@ static const char *p5_intf_modes(unsigne
- * MAC port
- * @mac_port_config: Holding the way setting up the PHY attribute to a
- * certain MAC port
-+ * @mac_pcs_an_restart Holding the way restarting PCS autonegotiation for a
-+ * certain MAC port
-+ * @mac_pcs_link_up: Holding the way setting up the PHY attribute to the pcs
-+ * of the certain MAC port
- */
- struct mt753x_info {
- enum mt753x_id id;
-@@ -474,6 +691,7 @@ struct mt753x_info {
- int (*phy_read)(struct dsa_switch *ds, int port, int regnum);
- int (*phy_write)(struct dsa_switch *ds, int port, int regnum, u16 val);
- int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface);
-+ int (*cpu_port_config)(struct dsa_switch *ds, int port);
- bool (*phy_mode_supported)(struct dsa_switch *ds, int port,
- const struct phylink_link_state *state);
- void (*mac_port_validate)(struct dsa_switch *ds, int port,
-@@ -483,6 +701,10 @@ struct mt753x_info {
- int (*mac_port_config)(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface);
-+ void (*mac_pcs_an_restart)(struct dsa_switch *ds, int port);
-+ void (*mac_pcs_link_up)(struct dsa_switch *ds, int port,
-+ unsigned int mode, phy_interface_t interface,
-+ int speed, int duplex);
- };
-
- /* struct mt7530_priv - This is the main data structure for holding the state
diff --git a/target/linux/mediatek/patches-5.4/0605-arm64-dts-mt7622-add-mt7531-dsa-to-bananapi-bpi-r64-board.patch b/target/linux/mediatek/patches-5.4/0605-arm64-dts-mt7622-add-mt7531-dsa-to-bananapi-bpi-r64-board.patch
deleted file mode 100644
index 8c3fe52089..0000000000
--- a/target/linux/mediatek/patches-5.4/0605-arm64-dts-mt7622-add-mt7531-dsa-to-bananapi-bpi-r64-board.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From: Landen Chao <landen.chao@mediatek.com>
-Subject: [PATCH net-next 6/6] arm64: dts: mt7622: add mt7531 dsa to
- bananapi-bpi-r64 board
-Date: Tue, 10 Dec 2019 16:14:42 +0800
-
-Add mt7531 dsa to bananapi-bpi-r64 board for 5 giga Ethernet ports support.
-
-Signed-off-by: Landen Chao <landen.chao@mediatek.com>
----
- .../dts/mediatek/mt7622-bananapi-bpi-r64.dts | 50 +++++++++++++++++++
- 1 file changed, 50 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-@@ -150,6 +150,56 @@
- mdio: mdio-bus {
- #address-cells = <1>;
- #size-cells = <0>;
-+
-+ switch@0 {
-+ compatible = "mediatek,mt7531";
-+ reg = <0>;
-+ reset-gpios = <&pio 54 0>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan0";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan1";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan2";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "lan3";
-+ };
-+
-+ port@6 {
-+ reg = <6>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+ phy-mode = "2500base-x";
-+
-+ fixed-link {
-+ speed = <2500>;
-+ full-duplex;
-+ pause;
-+ };
-+ };
-+ };
-+ };
-+
- };
- };
-
diff --git a/target/linux/mediatek/patches-5.4/0900-bt-mtk-serial-fix.patch b/target/linux/mediatek/patches-5.4/0900-bt-mtk-serial-fix.patch
deleted file mode 100644
index 872b2bad45..0000000000
--- a/target/linux/mediatek/patches-5.4/0900-bt-mtk-serial-fix.patch
+++ /dev/null
@@ -1,33 +0,0 @@
---- a/drivers/tty/serial/8250/8250.h
-+++ b/drivers/tty/serial/8250/8250.h
-@@ -82,6 +82,7 @@ struct serial8250_config {
- #define UART_CAP_MINI (1 << 17) /* Mini UART on BCM283X family lacks:
- * STOP PARITY EPAR SPAR WLEN5 WLEN6
- */
-+#define UART_CAP_NMOD (1 << 18) /* UART doesn't do termios */
-
- #define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */
- #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */
---- a/drivers/tty/serial/8250/8250_port.c
-+++ b/drivers/tty/serial/8250/8250_port.c
-@@ -290,7 +290,7 @@ static const struct serial8250_config ua
- .tx_loadsz = 16,
- .fcr = UART_FCR_ENABLE_FIFO |
- UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
-- .flags = UART_CAP_FIFO,
-+ .flags = UART_CAP_FIFO | UART_CAP_NMOD,
- },
- [PORT_NPCM] = {
- .name = "Nuvoton 16550",
-@@ -2597,6 +2597,11 @@ serial8250_do_set_termios(struct uart_po
- unsigned long flags;
- unsigned int baud, quot, frac = 0;
-
-+ if (up->capabilities & UART_CAP_NMOD) {
-+ termios->c_cflag = 0;
-+ return;
-+ }
-+
- if (up->capabilities & UART_CAP_MINI) {
- termios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CMSPAR);
- if ((termios->c_cflag & CSIZE) == CS5 ||
diff --git a/target/linux/mediatek/patches-5.4/0990-gsw-rtl8367s-mt7622-support.patch b/target/linux/mediatek/patches-5.4/0990-gsw-rtl8367s-mt7622-support.patch
deleted file mode 100644
index a3d49e903e..0000000000
--- a/target/linux/mediatek/patches-5.4/0990-gsw-rtl8367s-mt7622-support.patch
+++ /dev/null
@@ -1,23 +0,0 @@
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -42,6 +42,12 @@ config MDIO_BCM_IPROC
- This module provides a driver for the MDIO busses found in the
- Broadcom iProc SoC's.
-
-+config RTL8367S_GSW
-+ tristate "rtl8367 Gigabit Switch support for mt7622"
-+ depends on NET_VENDOR_MEDIATEK
-+ help
-+ This driver supports rtl8367s in mt7622
-+
- config MDIO_BCM_UNIMAC
- tristate "Broadcom UniMAC MDIO bus controller"
- depends on HAS_IOMEM
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -110,4 +110,5 @@ obj-$(CONFIG_TERANETICS_PHY) += teraneti
- obj-$(CONFIG_VITESSE_PHY) += vitesse.o
- obj-$(CONFIG_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o
- obj-$(CONFIG_MT753X_GSW) += mtk/mt753x/
-+obj-$(CONFIG_RTL8367S_GSW) += rtk/
-
diff --git a/target/linux/mediatek/patches-5.4/0991-dt-bindings-PCI-Mediatek-Update-PCIe-binding.patch b/target/linux/mediatek/patches-5.4/0991-dt-bindings-PCI-Mediatek-Update-PCIe-binding.patch
deleted file mode 100644
index 02e4c130ea..0000000000
--- a/target/linux/mediatek/patches-5.4/0991-dt-bindings-PCI-Mediatek-Update-PCIe-binding.patch
+++ /dev/null
@@ -1,415 +0,0 @@
-From patchwork Thu May 28 06:16:45 2020
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Chuanjia Liu <chuanjia.liu@mediatek.com>
-X-Patchwork-Id: 11574793
-Return-Path:
- <SRS0=ftSA=7K=lists.infradead.org=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@kernel.org>
-Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org
- [172.30.200.123])
- by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 391201392
- for <patchwork-linux-mediatek@patchwork.kernel.org>;
- Thu, 28 May 2020 06:20:27 +0000 (UTC)
-Received: from bombadil.infradead.org (bombadil.infradead.org
- [198.137.202.133])
- (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
- (No client certificate requested)
- by mail.kernel.org (Postfix) with ESMTPS id 104F620657
- for <patchwork-linux-mediatek@patchwork.kernel.org>;
- Thu, 28 May 2020 06:20:27 +0000 (UTC)
-Authentication-Results: mail.kernel.org;
- dkim=pass (2048-bit key) header.d=lists.infradead.org
- header.i=@lists.infradead.org header.b="raZHaWxs";
- dkim=fail reason="signature verification failed" (1024-bit key)
- header.d=mediatek.com header.i=@mediatek.com header.b="YztrByG/"
-DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 104F620657
-Authentication-Results: mail.kernel.org;
- dmarc=fail (p=none dis=none) header.from=mediatek.com
-Authentication-Results: mail.kernel.org;
- spf=none
- smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org
-DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
- d=lists.infradead.org; s=bombadil.20170209; h=Sender:
- Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post:
- List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:
- Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description:
- Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:
- List-Owner; bh=aVtKU+Ey8KEM97+S66fz9ZMo+H8BP570jhAAvaRsNWc=; b=raZHaWxsfCxsrd
- Byn/w1oLN/J82ApnNdBBXixq9Qj0uXIU2tBVqkiQ9lG6QDk7uguxQSJLeTqrsI/uxQmCI/PGQtZdP
- sH0oboi2sbQSqJ/1ud4uL2pPaiLRJCxINF5oWjoZMsjn/b2fWvn52P6vTr/dxDTaabiVhY0HL0J+X
- 7YGc1aYtO76HZHE2ke3puR42QkI8hE9E2cEhiLWeuUiLdUBegNM5MdYftu4nJTcCXnAeJjp/wIpYG
- 7X737N9cmanDf6Bxr2bNPgaYzH+m7JK6eGxuAvWo0+PE9OX7MLrXY3KjixcjD/b0he0mfEM++gBAq
- KBYKl5wh1mnlR2WIWXew==;
-Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org)
- by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux))
- id 1jeBtx-0005JC-DJ; Thu, 28 May 2020 06:20:25 +0000
-Received: from mailgw01.mediatek.com ([216.200.240.184])
- by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux))
- id 1jeBtW-0002f2-75; Thu, 28 May 2020 06:20:01 +0000
-X-UUID: d5cb6d96c2a5421796c2f8a284ff3670-20200527
-DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
- d=mediatek.com;
- s=dk;
- h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From;
- bh=EqjC+5cHgv6eykN7FPf2mtwK9UivJ3XSCE0jEvb8h+8=;
- b=YztrByG/Ia304l9KDPBwoHFYkFCN6qBXPqwZgg56CA9VitadAg2+K1VgfEU+oHqsqcsGAMdZTRMQh17tpm4bJParw6MMzAQ28te2TcxvQMV8PZMkerJdZyyYblI7ybauPWuofAQgQMtuwSKVii8eTRJbf99OZ9vDGJP3zo2j1wU=;
-X-UUID: d5cb6d96c2a5421796c2f8a284ff3670-20200527
-Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by
- mailgw01.mediatek.com
- (envelope-from <chuanjia.liu@mediatek.com>)
- (musrelay.mediatek.com ESMTP with TLS)
- with ESMTP id 681958707; Wed, 27 May 2020 22:20:16 -0800
-Received: from MTKMBS07N2.mediatek.inc (172.21.101.141) by
- MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id
- 15.0.1497.2; Wed, 27 May 2020 23:18:52 -0700
-Received: from mtkcas07.mediatek.inc (172.21.101.84) by
- mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id
- 15.0.1497.2; Thu, 28 May 2020 14:18:49 +0800
-Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc
- (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend
- Transport; Thu, 28 May 2020 14:18:47 +0800
-From: <chuanjia.liu@mediatek.com>
-To: <robh+dt@kernel.org>, <ryder.lee@mediatek.com>, <matthias.bgg@gmail.com>
-Subject: [PATCH v2 1/4] dt-bindings: PCI: Mediatek: Update PCIe binding
-Date: Thu, 28 May 2020 14:16:45 +0800
-Message-ID: <20200528061648.32078-2-chuanjia.liu@mediatek.com>
-X-Mailer: git-send-email 2.18.0
-In-Reply-To: <20200528061648.32078-1-chuanjia.liu@mediatek.com>
-References: <20200528061648.32078-1-chuanjia.liu@mediatek.com>
-MIME-Version: 1.0
-X-MTK: N
-X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3
-X-CRM114-CacheID: sfid-20200527_231958_261064_608CC03E
-X-CRM114-Status: GOOD ( 13.95 )
-X-Spam-Score: -0.2 (/)
-X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary:
- Content analysis details: (-0.2 points)
- pts rule name description
- ---- ----------------------
- --------------------------------------------------
- -0.0 SPF_PASS SPF: sender matches SPF record
- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record
- 0.0 MIME_BASE64_TEXT RAW: Message text disguised using base64
- encoding
- -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from
- author's domain
- 0.1 DKIM_SIGNED Message has a DKIM or DK signature,
- not necessarily
- valid
- -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
- -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from
- envelope-from domain
- 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay
- lines
-X-BeenThere: linux-mediatek@lists.infradead.org
-X-Mailman-Version: 2.1.29
-Precedence: list
-List-Id: <linux-mediatek.lists.infradead.org>
-List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-mediatek>,
- <mailto:linux-mediatek-request@lists.infradead.org?subject=unsubscribe>
-List-Archive: <http://lists.infradead.org/pipermail/linux-mediatek/>
-List-Post: <mailto:linux-mediatek@lists.infradead.org>
-List-Help: <mailto:linux-mediatek-request@lists.infradead.org?subject=help>
-List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-mediatek>,
- <mailto:linux-mediatek-request@lists.infradead.org?subject=subscribe>
-Cc: devicetree@vger.kernel.org, lorenzo.pieralisi@arm.com,
- srv_heupstream@mediatek.com, "chuanjia.liu" <Chuanjia.Liu@mediatek.com>,
- linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
- jianjun.wang@mediatek.com, linux-mediatek@lists.infradead.org,
- yong.wu@mediatek.com, bhelgaas@google.com,
- linux-arm-kernel@lists.infradead.org, amurray@thegoodpenguin.co.uk
-Sender: "Linux-mediatek" <linux-mediatek-bounces@lists.infradead.org>
-Errors-To:
- linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org
-
-From: "chuanjia.liu" <Chuanjia.Liu@mediatek.com>
-
-There are two independent PCIe controllers in MT2712/MT7622 platform,
-and each of them should contain an independent MSI domain.
-
-In current architecture, MSI domain will be inherited from the root
-bridge, and all of the devices will share the same MSI domain.
-Hence that, the PCIe devices will not work properly if the irq number
-which required is more than 32.
-
-Split the PCIe node for MT2712/MT7622 platform to fix MSI issue and
-comply with the hardware design.
-
-Signed-off-by: chuanjia.liu <Chuanjia.Liu@mediatek.com>
----
- .../bindings/pci/mediatek-pcie-cfg.yaml | 38 +++++
- .../devicetree/bindings/pci/mediatek-pcie.txt | 144 +++++++++++-------
- 2 files changed, 129 insertions(+), 53 deletions(-)
- create mode 100644 Documentation/devicetree/bindings/pci/mediatek-pcie-cfg.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pci/mediatek-pcie-cfg.yaml
-@@ -0,0 +1,38 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/pci/mediatek-pcie-cfg.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Mediatek PCIECFG controller
-+
-+maintainers:
-+ - Chuanjia Liu <chuanjia.liu@mediatek.com>
-+ - Jianjun Wang <jianjun.wang@mediatek.com>
-+
-+description: |
-+ The MediaTek PCIECFG controller controls some feature about
-+ LTSSM, ASPM and so on.
-+
-+properties:
-+ compatible:
-+ items:
-+ - enum:
-+ - mediatek,mt7622-pciecfg
-+ - mediatek,mt7629-pciecfg
-+ - const: syscon
-+
-+ reg:
-+ maxItems: 1
-+
-+required:
-+ - compatible
-+ - reg
-+
-+examples:
-+ - |
-+ pciecfg: pciecfg@1a140000 {
-+ compatible = "mediatek,mt7622-pciecfg", "syscon";
-+ reg = <0 0x1a140000 0 0x1000>;
-+ };
-+...
---- a/Documentation/devicetree/bindings/pci/mediatek-pcie.txt
-+++ b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt
-@@ -8,7 +8,7 @@ Required properties:
- "mediatek,mt7623-pcie"
- "mediatek,mt7629-pcie"
- - device_type: Must be "pci"
--- reg: Base addresses and lengths of the PCIe subsys and root ports.
-+- reg: Base addresses and lengths of the root ports.
- - reg-names: Names of the above areas to use during resource lookup.
- - #address-cells: Address representation for root ports (must be 3)
- - #size-cells: Size representation for root ports (must be 2)
-@@ -19,10 +19,10 @@ Required properties:
- - sys_ckN :transaction layer and data link layer clock
- Required entries for MT2701/MT7623:
- - free_ck :for reference clock of PCIe subsys
-- Required entries for MT2712/MT7622:
-+ Required entries for MT2712/MT7622/MT7629:
- - ahb_ckN :AHB slave interface operating clock for CSR access and RC
- initiated MMIO access
-- Required entries for MT7622:
-+ Required entries for MT7622/MT7629:
- - axi_ckN :application layer MMIO channel operating clock
- - aux_ckN :pe2_mac_bridge and pe2_mac_core operating clock when
- pcie_mac_ck/pcie_pipe_ck is turned off
-@@ -47,10 +47,13 @@ Required properties for MT7623/MT2701:
- - reset-names: Must be "pcie-rst0", "pcie-rst1", "pcie-rstN".. based on the
- number of root ports.
-
--Required properties for MT2712/MT7622:
-+Required properties for MT2712/MT7622/MT7629:
- -interrupts: A list of interrupt outputs of the controller, must have one
- entry for each PCIe port
-
-+Required properties for MT7622/MT7629:
-+- mediatek,pcie-subsys: Should be a phandle of the pciecfg node.
-+
- In addition, the device tree node must have sub-nodes describing each
- PCIe port interface, having the following mandatory properties:
-
-@@ -143,56 +146,73 @@ Examples for MT7623:
-
- Examples for MT2712:
-
-- pcie: pcie@11700000 {
-+ pcie1: pcie@112ff000 {
- compatible = "mediatek,mt2712-pcie";
- device_type = "pci";
-- reg = <0 0x11700000 0 0x1000>,
-- <0 0x112ff000 0 0x1000>;
-- reg-names = "port0", "port1";
-+ reg = <0 0x112ff000 0 0x1000>;
-+ reg-names = "port1";
- #address-cells = <3>;
- #size-cells = <2>;
-- interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
-- <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
-- clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>,
-- <&topckgen CLK_TOP_PE2_MAC_P1_SEL>,
-- <&pericfg CLK_PERI_PCIE0>,
-+ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
-+ interrupt-names = "pcie_irq";
-+ clocks = <&topckgen CLK_TOP_PE2_MAC_P1_SEL>,
- <&pericfg CLK_PERI_PCIE1>;
-- clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1";
-- phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>;
-- phy-names = "pcie-phy0", "pcie-phy1";
-+ clock-names = "sys_ck1", "ahb_ck1";
-+ phys = <&u3port1 PHY_TYPE_PCIE>;
-+ phy-names = "pcie-phy1";
- bus-range = <0x00 0xff>;
-- ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>;
-+ ranges = <0x82000000 0 0x11400000 0x0 0x11400000 0 0x300000>;
-+ status = "disabled";
-
-- pcie0: pcie@0,0 {
-- reg = <0x0000 0 0 0 0>;
-+ slot1: pcie@1,0 {
-+ reg = <0x0800 0 0 0 0>;
- #address-cells = <3>;
- #size-cells = <2>;
- #interrupt-cells = <1>;
- ranges;
- interrupt-map-mask = <0 0 0 7>;
-- interrupt-map = <0 0 0 1 &pcie_intc0 0>,
-- <0 0 0 2 &pcie_intc0 1>,
-- <0 0 0 3 &pcie_intc0 2>,
-- <0 0 0 4 &pcie_intc0 3>;
-- pcie_intc0: interrupt-controller {
-+ interrupt-map = <0 0 0 1 &pcie_intc1 0>,
-+ <0 0 0 2 &pcie_intc1 1>,
-+ <0 0 0 3 &pcie_intc1 2>,
-+ <0 0 0 4 &pcie_intc1 3>;
-+ pcie_intc1: interrupt-controller {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <1>;
- };
- };
-+ };
-
-- pcie1: pcie@1,0 {
-- reg = <0x0800 0 0 0 0>;
-+ pcie0: pcie@11700000 {
-+ compatible = "mediatek,mt2712-pcie";
-+ device_type = "pci";
-+ reg = <0 0x11700000 0 0x1000>;
-+ reg-names = "port0";
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
-+ interrupt-names = "pcie_irq";
-+ clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>,
-+ <&pericfg CLK_PERI_PCIE0>;
-+ clock-names = "sys_ck0", "ahb_ck0";
-+ phys = <&u3port0 PHY_TYPE_PCIE>;
-+ phy-names = "pcie-phy0";
-+ bus-range = <0x00 0xff>;
-+ ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>;
-+ status = "disabled";
-+
-+ slot0: pcie@0,0 {
-+ reg = <0x0000 0 0 0 0>;
- #address-cells = <3>;
- #size-cells = <2>;
- #interrupt-cells = <1>;
- ranges;
- interrupt-map-mask = <0 0 0 7>;
-- interrupt-map = <0 0 0 1 &pcie_intc1 0>,
-- <0 0 0 2 &pcie_intc1 1>,
-- <0 0 0 3 &pcie_intc1 2>,
-- <0 0 0 4 &pcie_intc1 3>;
-- pcie_intc1: interrupt-controller {
-+ interrupt-map = <0 0 0 1 &pcie_intc0 0>,
-+ <0 0 0 2 &pcie_intc0 1>,
-+ <0 0 0 3 &pcie_intc0 2>,
-+ <0 0 0 4 &pcie_intc0 3>;
-+ pcie_intc0: interrupt-controller {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <1>;
-@@ -202,39 +222,31 @@ Examples for MT2712:
-
- Examples for MT7622:
-
-- pcie: pcie@1a140000 {
-+ pcie0: pcie@1a143000 {
- compatible = "mediatek,mt7622-pcie";
- device_type = "pci";
-- reg = <0 0x1a140000 0 0x1000>,
-- <0 0x1a143000 0 0x1000>,
-- <0 0x1a145000 0 0x1000>;
-- reg-names = "subsys", "port0", "port1";
-+ reg = <0 0x1a143000 0 0x1000>;
-+ reg-names = "port0";
-+ mediatek,pcie-cfg = <&pciecfg>;
- #address-cells = <3>;
- #size-cells = <2>;
-- interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_LOW>,
-- <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>;
-+ interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_LOW>;
-+ interrupt-names = "pcie_irq";
- clocks = <&pciesys CLK_PCIE_P0_MAC_EN>,
-- <&pciesys CLK_PCIE_P1_MAC_EN>,
- <&pciesys CLK_PCIE_P0_AHB_EN>,
-- <&pciesys CLK_PCIE_P1_AHB_EN>,
- <&pciesys CLK_PCIE_P0_AUX_EN>,
-- <&pciesys CLK_PCIE_P1_AUX_EN>,
- <&pciesys CLK_PCIE_P0_AXI_EN>,
-- <&pciesys CLK_PCIE_P1_AXI_EN>,
- <&pciesys CLK_PCIE_P0_OBFF_EN>,
-- <&pciesys CLK_PCIE_P1_OBFF_EN>,
-- <&pciesys CLK_PCIE_P0_PIPE_EN>,
-- <&pciesys CLK_PCIE_P1_PIPE_EN>;
-- clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1",
-- "aux_ck0", "aux_ck1", "axi_ck0", "axi_ck1",
-- "obff_ck0", "obff_ck1", "pipe_ck0", "pipe_ck1";
-- phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>;
-- phy-names = "pcie-phy0", "pcie-phy1";
-+ <&pciesys CLK_PCIE_P0_PIPE_EN>;
-+ clock-names = "sys_ck0", "ahb_ck0", "aux_ck0",
-+ "axi_ck0", "obff_ck0", "pipe_ck0";
-+
- power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
- bus-range = <0x00 0xff>;
-- ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>;
-+ ranges = <0x82000000 0 0x20000000 0 0x20000000 0 0x8000000>;
-+ status = "disabled";
-
-- pcie0: pcie@0,0 {
-+ slot0: pcie@0,0 {
- reg = <0x0000 0 0 0 0>;
- #address-cells = <3>;
- #size-cells = <2>;
-@@ -251,8 +263,34 @@ Examples for MT7622:
- #interrupt-cells = <1>;
- };
- };
-+ };
-+
-+ pcie1: pcie@1a145000 {
-+ compatible = "mediatek,mt7622-pcie";
-+ device_type = "pci";
-+ reg = <0 0x1a145000 0 0x1000>;
-+ reg-names = "port1";
-+ mediatek,pcie-cfg = <&pciecfg>;
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>;
-+ interrupt-names = "pcie_irq";
-+ clocks = <&pciesys CLK_PCIE_P1_MAC_EN>,
-+ /* designer has connect RC1 with p0_ahb clock */
-+ <&pciesys CLK_PCIE_P0_AHB_EN>,
-+ <&pciesys CLK_PCIE_P1_AUX_EN>,
-+ <&pciesys CLK_PCIE_P1_AXI_EN>,
-+ <&pciesys CLK_PCIE_P1_OBFF_EN>,
-+ <&pciesys CLK_PCIE_P1_PIPE_EN>;
-+ clock-names = "sys_ck1", "ahb_ck1", "aux_ck1",
-+ "axi_ck1", "obff_ck1", "pipe_ck1";
-+
-+ power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
-+ bus-range = <0x00 0xff>;
-+ ranges = <0x82000000 0 0x28000000 0 0x28000000 0 0x8000000>;
-+ status = "disabled";
-
-- pcie1: pcie@1,0 {
-+ slot1: pcie@1,0 {
- reg = <0x0800 0 0 0 0>;
- #address-cells = <3>;
- #size-cells = <2>;
diff --git a/target/linux/mediatek/patches-5.4/0992-PCI-mediatek-Use-regmap-to-get-shared-pcie-cfg-base.patch b/target/linux/mediatek/patches-5.4/0992-PCI-mediatek-Use-regmap-to-get-shared-pcie-cfg-base.patch
deleted file mode 100644
index 3e4d44f59e..0000000000
--- a/target/linux/mediatek/patches-5.4/0992-PCI-mediatek-Use-regmap-to-get-shared-pcie-cfg-base.patch
+++ /dev/null
@@ -1,217 +0,0 @@
-From patchwork Thu May 28 06:16:46 2020
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Chuanjia Liu <chuanjia.liu@mediatek.com>
-X-Patchwork-Id: 11574781
-Return-Path:
- <SRS0=ftSA=7K=lists.infradead.org=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@kernel.org>
-Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org
- [172.30.200.123])
- by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0A99B60D
- for <patchwork-linux-mediatek@patchwork.kernel.org>;
- Thu, 28 May 2020 06:19:04 +0000 (UTC)
-Received: from bombadil.infradead.org (bombadil.infradead.org
- [198.137.202.133])
- (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
- (No client certificate requested)
- by mail.kernel.org (Postfix) with ESMTPS id DCC99208FE
- for <patchwork-linux-mediatek@patchwork.kernel.org>;
- Thu, 28 May 2020 06:19:03 +0000 (UTC)
-Authentication-Results: mail.kernel.org;
- dkim=pass (2048-bit key) header.d=lists.infradead.org
- header.i=@lists.infradead.org header.b="SpOi0ueF";
- dkim=fail reason="signature verification failed" (1024-bit key)
- header.d=mediatek.com header.i=@mediatek.com header.b="UGIBoIEG"
-DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DCC99208FE
-Authentication-Results: mail.kernel.org;
- dmarc=fail (p=none dis=none) header.from=mediatek.com
-Authentication-Results: mail.kernel.org;
- spf=none
- smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org
-DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
- d=lists.infradead.org; s=bombadil.20170209; h=Sender:
- Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post:
- List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:
- Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description:
- Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:
- List-Owner; bh=LIr5poLUT/UdH6/akh/pnICGGa3rUBkN+4FhE1DyOrU=; b=SpOi0ueFcoJ/ka
- 4esa6cDd5oU4fp0z684ZVPaVvvhm/azSZBBMYinHaAW6EvzKcMNYIX9grP8eg/728lEPNTKVq0I8H
- PQZ9KvD4uTu8Opo1hD8LsRSLr+YLpNKt3KPOY/4gpwQ97uU9rI5PwkuAxPBgR949Vh5EiG0Vaww1H
- Ep+I5BFRn2LVVQZP1Z7U0A0VUcOTLJ4znoWRLEXxtM9/Wd4hwQsrEPQszeDFti/RbwGfJ5efOb5UL
- fhwBzSxELEzAAgH7env/XD2sSSpVf2Qsn6WO8D3ZepMtWrRtARiaRKSNxSBQTg2SSHcjmBSJSzcX+
- w8wqWaUMs0crlBuZWS1g==;
-Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org)
- by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux))
- id 1jeBsc-0001tI-88; Thu, 28 May 2020 06:19:02 +0000
-Received: from mailgw01.mediatek.com ([216.200.240.184])
- by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux))
- id 1jeBsZ-0001rp-6g; Thu, 28 May 2020 06:19:01 +0000
-X-UUID: beeaf5765357439c91eab1f67ca7ef43-20200527
-DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
- d=mediatek.com;
- s=dk;
- h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From;
- bh=+IjWjsF/DhknqZB+lLSZ50cyvxDap+8w4tvqhp8Dv68=;
- b=UGIBoIEGJUuq5pEvYEad1HVGpiv6yma+94hva83D2gD8lYmihRWkpJxB2yn+dVtNm7ZXXoQBf+jvvULOmslJgs1HZTLJTnjpdvLmQqo42OXRXSVpTE49HdRkJZDAIWIAReBfOEkFgNxcIX3uedrtnww/NLJ2lagrYPG5ET4lI2E=;
-X-UUID: beeaf5765357439c91eab1f67ca7ef43-20200527
-Received: from mtkcas68.mediatek.inc [(172.29.94.19)] by mailgw01.mediatek.com
- (envelope-from <chuanjia.liu@mediatek.com>)
- (musrelay.mediatek.com ESMTP with TLS)
- with ESMTP id 603406343; Wed, 27 May 2020 22:19:17 -0800
-Received: from mtkmbs07n1.mediatek.inc (172.21.101.16) by
- MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id
- 15.0.1497.2; Wed, 27 May 2020 23:18:47 -0700
-Received: from mtkcas07.mediatek.inc (172.21.101.84) by
- mtkmbs07n1.mediatek.inc (172.21.101.16) with Microsoft SMTP Server (TLS) id
- 15.0.1497.2; Thu, 28 May 2020 14:18:51 +0800
-Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc
- (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend
- Transport; Thu, 28 May 2020 14:18:49 +0800
-From: <chuanjia.liu@mediatek.com>
-To: <robh+dt@kernel.org>, <ryder.lee@mediatek.com>, <matthias.bgg@gmail.com>
-Subject: [PATCH v2 2/4] PCI: mediatek: Use regmap to get shared pcie-cfg base
-Date: Thu, 28 May 2020 14:16:46 +0800
-Message-ID: <20200528061648.32078-3-chuanjia.liu@mediatek.com>
-X-Mailer: git-send-email 2.18.0
-In-Reply-To: <20200528061648.32078-1-chuanjia.liu@mediatek.com>
-References: <20200528061648.32078-1-chuanjia.liu@mediatek.com>
-MIME-Version: 1.0
-X-MTK: N
-X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3
-X-CRM114-CacheID: sfid-20200527_231859_251275_BED2B1E2
-X-CRM114-Status: GOOD ( 11.62 )
-X-Spam-Score: -0.2 (/)
-X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary:
- Content analysis details: (-0.2 points)
- pts rule name description
- ---- ----------------------
- --------------------------------------------------
- -0.0 SPF_PASS SPF: sender matches SPF record
- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record
- 0.0 MIME_BASE64_TEXT RAW: Message text disguised using base64
- encoding
- -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from
- author's domain
- 0.1 DKIM_SIGNED Message has a DKIM or DK signature,
- not necessarily
- valid
- -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
- -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from
- envelope-from domain
- 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay
- lines
-X-BeenThere: linux-mediatek@lists.infradead.org
-X-Mailman-Version: 2.1.29
-Precedence: list
-List-Id: <linux-mediatek.lists.infradead.org>
-List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-mediatek>,
- <mailto:linux-mediatek-request@lists.infradead.org?subject=unsubscribe>
-List-Archive: <http://lists.infradead.org/pipermail/linux-mediatek/>
-List-Post: <mailto:linux-mediatek@lists.infradead.org>
-List-Help: <mailto:linux-mediatek-request@lists.infradead.org?subject=help>
-List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-mediatek>,
- <mailto:linux-mediatek-request@lists.infradead.org?subject=subscribe>
-Cc: devicetree@vger.kernel.org, lorenzo.pieralisi@arm.com,
- srv_heupstream@mediatek.com, "chuanjia.liu" <Chuanjia.Liu@mediatek.com>,
- linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
- jianjun.wang@mediatek.com, linux-mediatek@lists.infradead.org,
- yong.wu@mediatek.com, bhelgaas@google.com,
- linux-arm-kernel@lists.infradead.org, amurray@thegoodpenguin.co.uk
-Sender: "Linux-mediatek" <linux-mediatek-bounces@lists.infradead.org>
-Errors-To:
- linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org
-
-From: "chuanjia.liu" <Chuanjia.Liu@mediatek.com>
-
-Use regmap to get shared pcie-cfg base and change
-the method to get pcie irq.
-
-Signed-off-by: chuanjia.liu <Chuanjia.Liu@mediatek.com>
----
- drivers/pci/controller/pcie-mediatek.c | 25 ++++++++++++++++++-------
- 1 file changed, 18 insertions(+), 7 deletions(-)
-
---- a/drivers/pci/controller/pcie-mediatek.c
-+++ b/drivers/pci/controller/pcie-mediatek.c
-@@ -14,6 +14,7 @@
- #include <linux/irqchip/chained_irq.h>
- #include <linux/irqdomain.h>
- #include <linux/kernel.h>
-+#include <linux/mfd/syscon.h>
- #include <linux/msi.h>
- #include <linux/module.h>
- #include <linux/of_address.h>
-@@ -23,6 +24,7 @@
- #include <linux/phy/phy.h>
- #include <linux/platform_device.h>
- #include <linux/pm_runtime.h>
-+#include <linux/regmap.h>
- #include <linux/reset.h>
-
- #include "../pci.h"
-@@ -205,6 +207,7 @@ struct mtk_pcie_port {
- * struct mtk_pcie - PCIe host information
- * @dev: pointer to PCIe device
- * @base: IO mapped register base
-+ * @cfg: IO mapped register map for PCIe config
- * @free_ck: free-run reference clock
- * @mem: non-prefetchable memory resource
- * @ports: pointer to PCIe port information
-@@ -214,6 +217,7 @@ struct mtk_pcie_port {
- struct mtk_pcie {
- struct device *dev;
- void __iomem *base;
-+ struct regmap *cfg;
- struct clk *free_ck;
-
- struct resource mem;
-@@ -651,7 +655,7 @@ static int mtk_pcie_setup_irq(struct mtk
- return err;
- }
-
-- port->irq = platform_get_irq(pdev, port->slot);
-+ port->irq = platform_get_irq_byname(pdev, "pcie_irq");
- irq_set_chained_handler_and_data(port->irq,
- mtk_pcie_intr_handler, port);
-
-@@ -666,12 +670,11 @@ static int mtk_pcie_startup_port_v2(stru
- u32 val;
- int err;
-
-- /* MT7622 platforms need to enable LTSSM and ASPM from PCIe subsys */
-- if (pcie->base) {
-- val = readl(pcie->base + PCIE_SYS_CFG_V2);
-- val |= PCIE_CSR_LTSSM_EN(port->slot) |
-- PCIE_CSR_ASPM_L1_EN(port->slot);
-- writel(val, pcie->base + PCIE_SYS_CFG_V2);
-+ /* MT7622/MT7629 platforms need to enable LTSSM and ASPM. */
-+ if (pcie->cfg) {
-+ val = PCIE_CSR_LTSSM_EN(port->slot) |
-+ PCIE_CSR_ASPM_L1_EN(port->slot);
-+ regmap_update_bits(pcie->cfg, PCIE_SYS_CFG_V2, val, val);
- }
-
- /* Assert all reset signals */
-@@ -977,6 +980,7 @@ static int mtk_pcie_subsys_powerup(struc
- struct device *dev = pcie->dev;
- struct platform_device *pdev = to_platform_device(dev);
- struct resource *regs;
-+ struct device_node *cfg_node;
- int err;
-
- /* get shared registers, which are optional */
-@@ -989,6 +993,13 @@ static int mtk_pcie_subsys_powerup(struc
- }
- }
-
-+ cfg_node = of_parse_phandle(dev->of_node, "mediatek,pcie-cfg", 0);
-+ if (cfg_node) {
-+ pcie->cfg = syscon_node_to_regmap(cfg_node);
-+ if (IS_ERR(pcie->cfg))
-+ return PTR_ERR(pcie->cfg);
-+ }
-+
- pcie->free_ck = devm_clk_get(dev, "free_ck");
- if (IS_ERR(pcie->free_ck)) {
- if (PTR_ERR(pcie->free_ck) == -EPROBE_DEFER)
diff --git a/target/linux/mediatek/patches-5.4/0993-arm64-dts-mediatek-Split-PCIe-node-for-MT2712-MT7622.patch b/target/linux/mediatek/patches-5.4/0993-arm64-dts-mediatek-Split-PCIe-node-for-MT2712-MT7622.patch
deleted file mode 100644
index 3c5558b606..0000000000
--- a/target/linux/mediatek/patches-5.4/0993-arm64-dts-mediatek-Split-PCIe-node-for-MT2712-MT7622.patch
+++ /dev/null
@@ -1,417 +0,0 @@
-From patchwork Thu May 28 06:16:47 2020
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Chuanjia Liu <chuanjia.liu@mediatek.com>
-X-Patchwork-Id: 11574785
-Return-Path:
- <SRS0=ftSA=7K=lists.infradead.org=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@kernel.org>
-Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org
- [172.30.200.123])
- by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 933301391
- for <patchwork-linux-mediatek@patchwork.kernel.org>;
- Thu, 28 May 2020 06:19:16 +0000 (UTC)
-Received: from bombadil.infradead.org (bombadil.infradead.org
- [198.137.202.133])
- (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
- (No client certificate requested)
- by mail.kernel.org (Postfix) with ESMTPS id D19F02078C
- for <patchwork-linux-mediatek@patchwork.kernel.org>;
- Thu, 28 May 2020 06:19:15 +0000 (UTC)
-Authentication-Results: mail.kernel.org;
- dkim=pass (2048-bit key) header.d=lists.infradead.org
- header.i=@lists.infradead.org header.b="s8K7t7DF";
- dkim=fail reason="signature verification failed" (1024-bit key)
- header.d=mediatek.com header.i=@mediatek.com header.b="RhX81Iqp"
-DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D19F02078C
-Authentication-Results: mail.kernel.org;
- dmarc=fail (p=none dis=none) header.from=mediatek.com
-Authentication-Results: mail.kernel.org;
- spf=none
- smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org
-DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
- d=lists.infradead.org; s=bombadil.20170209; h=Sender:
- Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post:
- List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:
- Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description:
- Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:
- List-Owner; bh=NHyHqNMcE7LW10MwduOJoKiWe8cv+XayY+L6WDZeSu0=; b=s8K7t7DFh1iQ5w
- eGvuMRgXEQv/YWRuSZRyX8lx8R2H9IuawEIgkhO6lEo6xv0VdsRuj8SptfoWg5afCItMhih373M21
- 6sUy3tEiuKGgklfxLU0reLEkaATkKRGLJDY3eSSs1mvZDrydKuZLDTka+YDGaiESlOhqMr95Nm6YM
- yK8O00qTwSRPJUILRsBv1e/Kz8NRCmYhs56snABJkKeJ51NRAkb20R6qGTEd6UyBlz3jTVYwluLgF
- bdqzywDT6+BNg/Agh6Zd+v2PpO4cmwCpGm62+3UUyZkfi/aQ4qZ/AFAfSQI+3ZBAgsKMC1PGifOi/
- FgGxIvAUk6atBy7DAHuw==;
-Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org)
- by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux))
- id 1jeBsn-00025C-EF; Thu, 28 May 2020 06:19:13 +0000
-Received: from mailgw01.mediatek.com ([216.200.240.184])
- by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux))
- id 1jeBsZ-0001s4-6j; Thu, 28 May 2020 06:19:01 +0000
-X-UUID: c6210e6371fa445db0ae40a8b8a7a0a1-20200527
-DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
- d=mediatek.com;
- s=dk;
- h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From;
- bh=X9AwTdbhpWmlWY4LjTm8KLq4Cca3YI9UnyCX3O0BAak=;
- b=RhX81Iqp0mWhBDyMQMFSEtt23+DGAWoin1SrFGP1bzp6GEtu38b2pK5RJVBshJtuxi/a1uMXZjeDsHJn02VGdNA07FrzZ7jq6YYEL+8cJs2DnhySmNElZazXPv2vKu9TWygfilTT24h/u8V/eszuRuhkdoUKWol8LwDlPl9gskg=;
-X-UUID: c6210e6371fa445db0ae40a8b8a7a0a1-20200527
-Received: from mtkcas68.mediatek.inc [(172.29.94.19)] by mailgw01.mediatek.com
- (envelope-from <chuanjia.liu@mediatek.com>)
- (musrelay.mediatek.com ESMTP with TLS)
- with ESMTP id 7561992; Wed, 27 May 2020 22:19:17 -0800
-Received: from mtkmbs07n1.mediatek.inc (172.21.101.16) by
- MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id
- 15.0.1497.2; Wed, 27 May 2020 23:18:47 -0700
-Received: from mtkcas07.mediatek.inc (172.21.101.84) by
- mtkmbs07n1.mediatek.inc (172.21.101.16) with Microsoft SMTP Server (TLS) id
- 15.0.1497.2; Thu, 28 May 2020 14:18:52 +0800
-Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc
- (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend
- Transport; Thu, 28 May 2020 14:18:51 +0800
-From: <chuanjia.liu@mediatek.com>
-To: <robh+dt@kernel.org>, <ryder.lee@mediatek.com>, <matthias.bgg@gmail.com>
-Subject: [PATCH v2 3/4] arm64: dts: mediatek: Split PCIe node for
- MT2712/MT7622
-Date: Thu, 28 May 2020 14:16:47 +0800
-Message-ID: <20200528061648.32078-4-chuanjia.liu@mediatek.com>
-X-Mailer: git-send-email 2.18.0
-In-Reply-To: <20200528061648.32078-1-chuanjia.liu@mediatek.com>
-References: <20200528061648.32078-1-chuanjia.liu@mediatek.com>
-MIME-Version: 1.0
-X-MTK: N
-X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3
-X-CRM114-CacheID: sfid-20200527_231859_253529_B6751C5A
-X-CRM114-Status: GOOD ( 12.20 )
-X-Spam-Score: -0.2 (/)
-X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary:
- Content analysis details: (-0.2 points)
- pts rule name description
- ---- ----------------------
- --------------------------------------------------
- -0.0 SPF_PASS SPF: sender matches SPF record
- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record
- 0.0 MIME_BASE64_TEXT RAW: Message text disguised using base64
- encoding
- -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from
- author's domain
- 0.1 DKIM_SIGNED Message has a DKIM or DK signature,
- not necessarily
- valid
- -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
- -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from
- envelope-from domain
- 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay
- lines
-X-BeenThere: linux-mediatek@lists.infradead.org
-X-Mailman-Version: 2.1.29
-Precedence: list
-List-Id: <linux-mediatek.lists.infradead.org>
-List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-mediatek>,
- <mailto:linux-mediatek-request@lists.infradead.org?subject=unsubscribe>
-List-Archive: <http://lists.infradead.org/pipermail/linux-mediatek/>
-List-Post: <mailto:linux-mediatek@lists.infradead.org>
-List-Help: <mailto:linux-mediatek-request@lists.infradead.org?subject=help>
-List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-mediatek>,
- <mailto:linux-mediatek-request@lists.infradead.org?subject=subscribe>
-Cc: devicetree@vger.kernel.org, lorenzo.pieralisi@arm.com,
- srv_heupstream@mediatek.com, "chuanjia.liu" <Chuanjia.Liu@mediatek.com>,
- linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
- jianjun.wang@mediatek.com, linux-mediatek@lists.infradead.org,
- yong.wu@mediatek.com, bhelgaas@google.com,
- linux-arm-kernel@lists.infradead.org, amurray@thegoodpenguin.co.uk
-Sender: "Linux-mediatek" <linux-mediatek-bounces@lists.infradead.org>
-Errors-To:
- linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org
-
-From: "chuanjia.liu" <Chuanjia.Liu@mediatek.com>
-
-There are two independent PCIe controllers in MT2712/MT7622 platform,
-and each of them should contain an independent MSI domain.
-
-In current architecture, MSI domain will be inherited from the root
-bridge, and all of the devices will share the same MSI domain.
-Hence that, the PCIe devices will not work properly if the irq number
-which required is more than 32.
-
-Split the PCIe node for MT2712/MT7622 platform to fix MSI issue and
-comply with the hardware design.
-
-Signed-off-by: chuanjia.liu <Chuanjia.Liu@mediatek.com>
----
- arch/arm64/boot/dts/mediatek/mt2712e.dtsi | 75 +++++++++++--------
- .../dts/mediatek/mt7622-bananapi-bpi-r64.dts | 16 ++--
- arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 6 +-
- arch/arm64/boot/dts/mediatek/mt7622.dtsi | 68 +++++++++++------
- 4 files changed, 96 insertions(+), 69 deletions(-)
-
---- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
-@@ -791,60 +791,73 @@
- };
- };
-
-- pcie: pcie@11700000 {
-+ pcie1: pcie@112ff000 {
- compatible = "mediatek,mt2712-pcie";
- device_type = "pci";
-- reg = <0 0x11700000 0 0x1000>,
-- <0 0x112ff000 0 0x1000>;
-- reg-names = "port0", "port1";
-+ reg = <0 0x112ff000 0 0x1000>;
-+ reg-names = "port1";
- #address-cells = <3>;
- #size-cells = <2>;
-- interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
-- <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
-- clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>,
-- <&topckgen CLK_TOP_PE2_MAC_P1_SEL>,
-- <&pericfg CLK_PERI_PCIE0>,
-+ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
-+ interrupt-names = "pcie_irq";
-+ clocks = <&topckgen CLK_TOP_PE2_MAC_P1_SEL>,
- <&pericfg CLK_PERI_PCIE1>;
-- clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1";
-- phys = <&u3port0 PHY_TYPE_PCIE>, <&u3port1 PHY_TYPE_PCIE>;
-- phy-names = "pcie-phy0", "pcie-phy1";
-+ clock-names = "sys_ck1", "ahb_ck1";
-+ phys = <&u3port1 PHY_TYPE_PCIE>;
-+ phy-names = "pcie-phy1";
- bus-range = <0x00 0xff>;
-- ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>;
-+ ranges = <0x82000000 0 0x11400000 0x0 0x11400000 0 0x300000>;
-+ status = "disabled";
-
-- pcie0: pcie@0,0 {
-- device_type = "pci";
-- status = "disabled";
-- reg = <0x0000 0 0 0 0>;
-+ slot1: pcie@1,0 {
-+ reg = <0x0800 0 0 0 0>;
- #address-cells = <3>;
- #size-cells = <2>;
- #interrupt-cells = <1>;
- ranges;
- interrupt-map-mask = <0 0 0 7>;
-- interrupt-map = <0 0 0 1 &pcie_intc0 0>,
-- <0 0 0 2 &pcie_intc0 1>,
-- <0 0 0 3 &pcie_intc0 2>,
-- <0 0 0 4 &pcie_intc0 3>;
-- pcie_intc0: interrupt-controller {
-+ interrupt-map = <0 0 0 1 &pcie_intc1 0>,
-+ <0 0 0 2 &pcie_intc1 1>,
-+ <0 0 0 3 &pcie_intc1 2>,
-+ <0 0 0 4 &pcie_intc1 3>;
-+ pcie_intc1: interrupt-controller {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <1>;
- };
- };
-+ };
-
-- pcie1: pcie@1,0 {
-- device_type = "pci";
-- status = "disabled";
-- reg = <0x0800 0 0 0 0>;
-+ pcie0: pcie@11700000 {
-+ compatible = "mediatek,mt2712-pcie";
-+ device_type = "pci";
-+ reg = <0 0x11700000 0 0x1000>;
-+ reg-names = "port0";
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
-+ interrupt-names = "pcie_irq";
-+ clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>,
-+ <&pericfg CLK_PERI_PCIE0>;
-+ clock-names = "sys_ck0", "ahb_ck0";
-+ phys = <&u3port0 PHY_TYPE_PCIE>;
-+ phy-names = "pcie-phy0";
-+ bus-range = <0x00 0xff>;
-+ ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>;
-+ status = "disabled";
-+
-+ slot0: pcie@0,0 {
-+ reg = <0x0000 0 0 0 0>;
- #address-cells = <3>;
- #size-cells = <2>;
- #interrupt-cells = <1>;
- ranges;
- interrupt-map-mask = <0 0 0 7>;
-- interrupt-map = <0 0 0 1 &pcie_intc1 0>,
-- <0 0 0 2 &pcie_intc1 1>,
-- <0 0 0 3 &pcie_intc1 2>,
-- <0 0 0 4 &pcie_intc1 3>;
-- pcie_intc1: interrupt-controller {
-+ interrupt-map = <0 0 0 1 &pcie_intc0 0>,
-+ <0 0 0 2 &pcie_intc0 1>,
-+ <0 0 0 3 &pcie_intc0 2>,
-+ <0 0 0 4 &pcie_intc0 3>;
-+ pcie_intc0: interrupt-controller {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <1>;
---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-@@ -294,18 +294,16 @@
- };
- };
-
--&pcie {
-+&pcie0 {
- pinctrl-names = "default";
-- pinctrl-0 = <&pcie0_pins>, <&pcie1_pins>;
-+ pinctrl-0 = <&pcie0_pins>;
- status = "okay";
-+};
-
-- pcie@0,0 {
-- status = "okay";
-- };
--
-- pcie@1,0 {
-- status = "okay";
-- };
-+&pcie1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pcie1_pins>;
-+ status = "okay";
- };
-
- &pio {
---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -794,45 +794,41 @@
- #reset-cells = <1>;
- };
-
-- pcie: pcie@1a140000 {
-+ pciecfg: pciecfg@1a140000 {
-+ compatible = "mediatek,mt7622-pciecfg", "syscon";
-+ reg = <0 0x1a140000 0 0x1000>;
-+ };
-+
-+ pcie0: pcie@1a143000 {
- compatible = "mediatek,mt7622-pcie";
- device_type = "pci";
-- reg = <0 0x1a140000 0 0x1000>,
-- <0 0x1a143000 0 0x1000>,
-- <0 0x1a145000 0 0x1000>;
-- reg-names = "subsys", "port0", "port1";
-+ reg = <0 0x1a143000 0 0x1000>;
-+ reg-names = "port0";
-+ mediatek,pcie-cfg = <&pciecfg>;
- #address-cells = <3>;
- #size-cells = <2>;
-- interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_LOW>,
-- <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>;
-+ interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_LOW>;
-+ interrupt-names = "pcie_irq";
- clocks = <&pciesys CLK_PCIE_P0_MAC_EN>,
-- <&pciesys CLK_PCIE_P1_MAC_EN>,
-- <&pciesys CLK_PCIE_P0_AHB_EN>,
- <&pciesys CLK_PCIE_P0_AHB_EN>,
- <&pciesys CLK_PCIE_P0_AUX_EN>,
-- <&pciesys CLK_PCIE_P1_AUX_EN>,
- <&pciesys CLK_PCIE_P0_AXI_EN>,
-- <&pciesys CLK_PCIE_P1_AXI_EN>,
- <&pciesys CLK_PCIE_P0_OBFF_EN>,
-- <&pciesys CLK_PCIE_P1_OBFF_EN>,
-- <&pciesys CLK_PCIE_P0_PIPE_EN>,
-- <&pciesys CLK_PCIE_P1_PIPE_EN>;
-- clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1",
-- "aux_ck0", "aux_ck1", "axi_ck0", "axi_ck1",
-- "obff_ck0", "obff_ck1", "pipe_ck0", "pipe_ck1";
-+ <&pciesys CLK_PCIE_P0_PIPE_EN>;
-+ clock-names = "sys_ck0", "ahb_ck0", "aux_ck0",
-+ "axi_ck0", "obff_ck0", "pipe_ck0";
-+
- power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
- bus-range = <0x00 0xff>;
-- ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>;
-+ ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>;
- status = "disabled";
-
-- pcie0: pcie@0,0 {
-+ slot0: pcie@0,0 {
- reg = <0x0000 0 0 0 0>;
- #address-cells = <3>;
- #size-cells = <2>;
- #interrupt-cells = <1>;
- ranges;
-- status = "disabled";
--
- interrupt-map-mask = <0 0 0 7>;
- interrupt-map = <0 0 0 1 &pcie_intc0 0>,
- <0 0 0 2 &pcie_intc0 1>,
-@@ -844,15 +840,39 @@
- #interrupt-cells = <1>;
- };
- };
-+ };
-
-- pcie1: pcie@1,0 {
-+ pcie1: pcie@1a145000 {
-+ compatible = "mediatek,mt7622-pcie";
-+ device_type = "pci";
-+ reg = <0 0x1a145000 0 0x1000>;
-+ reg-names = "port1";
-+ mediatek,pcie-cfg = <&pciecfg>;
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>;
-+ interrupt-names = "pcie_irq";
-+ clocks = <&pciesys CLK_PCIE_P1_MAC_EN>,
-+ /* designer has connect RC1 with p0_ahb clock */
-+ <&pciesys CLK_PCIE_P0_AHB_EN>,
-+ <&pciesys CLK_PCIE_P1_AUX_EN>,
-+ <&pciesys CLK_PCIE_P1_AXI_EN>,
-+ <&pciesys CLK_PCIE_P1_OBFF_EN>,
-+ <&pciesys CLK_PCIE_P1_PIPE_EN>;
-+ clock-names = "sys_ck1", "ahb_ck1", "aux_ck1",
-+ "axi_ck1", "obff_ck1", "pipe_ck1";
-+
-+ power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
-+ bus-range = <0x00 0xff>;
-+ ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>;
-+ status = "disabled";
-+
-+ slot1: pcie@1,0 {
- reg = <0x0800 0 0 0 0>;
- #address-cells = <3>;
- #size-cells = <2>;
- #interrupt-cells = <1>;
- ranges;
-- status = "disabled";
--
- interrupt-map-mask = <0 0 0 7>;
- interrupt-map = <0 0 0 1 &pcie_intc1 0>,
- <0 0 0 2 &pcie_intc1 1>,
---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-@@ -254,18 +254,16 @@
- };
- };
-
--&pcie {
-+&pcie0 {
- pinctrl-names = "default";
-- pinctrl-0 = <&pcie0_pins>, <&pcie1_pins>;
-+ pinctrl-0 = <&pcie0_pins>;
- status = "okay";
-+};
-
-- pcie@0,0 {
-- status = "okay";
-- };
--
-- pcie@1,0 {
-- status = "okay";
-- };
-+&pcie1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pcie1_pins>;
-+ status = "okay";
- };
-
- &pio {
diff --git a/target/linux/mediatek/patches-5.4/0994-ARM-dts-mediatek-Update-mt7629-PCIe-node.patch b/target/linux/mediatek/patches-5.4/0994-ARM-dts-mediatek-Update-mt7629-PCIe-node.patch
deleted file mode 100644
index f166aa75de..0000000000
--- a/target/linux/mediatek/patches-5.4/0994-ARM-dts-mediatek-Update-mt7629-PCIe-node.patch
+++ /dev/null
@@ -1,203 +0,0 @@
-From patchwork Thu May 28 06:16:48 2020
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Chuanjia Liu <chuanjia.liu@mediatek.com>
-X-Patchwork-Id: 11574797
-Return-Path:
- <SRS0=ftSA=7K=lists.infradead.org=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@kernel.org>
-Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org
- [172.30.200.123])
- by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 30A5E1392
- for <patchwork-linux-mediatek@patchwork.kernel.org>;
- Thu, 28 May 2020 06:29:05 +0000 (UTC)
-Received: from bombadil.infradead.org (bombadil.infradead.org
- [198.137.202.133])
- (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
- (No client certificate requested)
- by mail.kernel.org (Postfix) with ESMTPS id 08B6320721
- for <patchwork-linux-mediatek@patchwork.kernel.org>;
- Thu, 28 May 2020 06:29:05 +0000 (UTC)
-Authentication-Results: mail.kernel.org;
- dkim=pass (2048-bit key) header.d=lists.infradead.org
- header.i=@lists.infradead.org header.b="auhxDafY";
- dkim=fail reason="signature verification failed" (1024-bit key)
- header.d=mediatek.com header.i=@mediatek.com header.b="Kj09Arxb"
-DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 08B6320721
-Authentication-Results: mail.kernel.org;
- dmarc=fail (p=none dis=none) header.from=mediatek.com
-Authentication-Results: mail.kernel.org;
- spf=none
- smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org
-DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
- d=lists.infradead.org; s=bombadil.20170209; h=Sender:
- Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post:
- List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:
- Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description:
- Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:
- List-Owner; bh=+QPxF1vlOH7StIZYuXJa3V40x8QVDxCLF9AFXHblB9M=; b=auhxDafYBeaUZO
- aYp2KVO8Aie0v4tYtRwBon7hF+x55JwD78SAxQR2RsSvrlOo9cMYYby+ToUWflVUWQ60FapAl+w+l
- nkEjIOrLBErHwxNOcsD8T5kjyCBMqlz4OMAQYUDNJ3fSugRlGhOtxkjCGd9ebB8N2Rvu6/U8P1A9n
- P15mEQoc+RLonR1+9mBgwTEXErjsraxkimTD4Txsp4IvMs3UdsMkP+r3OT5S/p+Uj6O9ES0h7xIon
- aL79KaVqRLHrfZxnrVwuGiecAiTp8qLy9clHuJU32NA6ZcXH1OnWipKApgp8Ck7ys80WPKaMrat9B
- XuskJ63w13DZAbCVvuGQ==;
-Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org)
- by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux))
- id 1jeC2J-00014n-M9; Thu, 28 May 2020 06:29:03 +0000
-Received: from mailgw02.mediatek.com ([216.200.240.185])
- by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux))
- id 1jeC2H-00013t-Li; Thu, 28 May 2020 06:29:03 +0000
-X-UUID: a4877c1586e64afeb2d6172e10605d2b-20200527
-DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
- d=mediatek.com;
- s=dk;
- h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From;
- bh=CIwcBFK1x0LbOjDt1BG6/knHFxDHRiqj8ov/jWEZDBY=;
- b=Kj09ArxbnLVTc9bpaVPT3jQrIVjhL87sSYyVF9dFypS976k78Ce9gZd0f4K3zAZbYZHYoQtuyOQ9TOeufQfgD+Cr+j5VR7pTdO2E1iXHFs/eQAz5gAjvjlK01z1JiunrLnn9dvIr6c1gEkjQHny0VpuZ1duxx79jwYusg/Nw6Wc=;
-X-UUID: a4877c1586e64afeb2d6172e10605d2b-20200527
-Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by
- mailgw02.mediatek.com
- (envelope-from <chuanjia.liu@mediatek.com>)
- (musrelay.mediatek.com ESMTP with TLS)
- with ESMTP id 899663677; Wed, 27 May 2020 22:29:21 -0800
-Received: from MTKMBS07N2.mediatek.inc (172.21.101.141) by
- MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id
- 15.0.1497.2; Wed, 27 May 2020 23:18:50 -0700
-Received: from mtkcas07.mediatek.inc (172.21.101.84) by
- mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id
- 15.0.1497.2; Thu, 28 May 2020 14:18:54 +0800
-Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc
- (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend
- Transport; Thu, 28 May 2020 14:18:52 +0800
-From: <chuanjia.liu@mediatek.com>
-To: <robh+dt@kernel.org>, <ryder.lee@mediatek.com>, <matthias.bgg@gmail.com>
-Subject: [PATCH v2 4/4] ARM: dts: mediatek: Update mt7629 PCIe node
-Date: Thu, 28 May 2020 14:16:48 +0800
-Message-ID: <20200528061648.32078-5-chuanjia.liu@mediatek.com>
-X-Mailer: git-send-email 2.18.0
-In-Reply-To: <20200528061648.32078-1-chuanjia.liu@mediatek.com>
-References: <20200528061648.32078-1-chuanjia.liu@mediatek.com>
-MIME-Version: 1.0
-X-MTK: N
-X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3
-X-CRM114-CacheID: sfid-20200527_232901_719172_E5A99C62
-X-CRM114-Status: GOOD ( 11.61 )
-X-Spam-Score: -0.2 (/)
-X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary:
- Content analysis details: (-0.2 points)
- pts rule name description
- ---- ----------------------
- --------------------------------------------------
- -0.0 SPF_PASS SPF: sender matches SPF record
- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record
- 0.0 MIME_BASE64_TEXT RAW: Message text disguised using base64
- encoding
- -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from
- author's domain
- 0.1 DKIM_SIGNED Message has a DKIM or DK signature,
- not necessarily
- valid
- -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
- -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from
- envelope-from domain
- 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay
- lines
-X-BeenThere: linux-mediatek@lists.infradead.org
-X-Mailman-Version: 2.1.29
-Precedence: list
-List-Id: <linux-mediatek.lists.infradead.org>
-List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-mediatek>,
- <mailto:linux-mediatek-request@lists.infradead.org?subject=unsubscribe>
-List-Archive: <http://lists.infradead.org/pipermail/linux-mediatek/>
-List-Post: <mailto:linux-mediatek@lists.infradead.org>
-List-Help: <mailto:linux-mediatek-request@lists.infradead.org?subject=help>
-List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-mediatek>,
- <mailto:linux-mediatek-request@lists.infradead.org?subject=subscribe>
-Cc: devicetree@vger.kernel.org, lorenzo.pieralisi@arm.com,
- srv_heupstream@mediatek.com, "chuanjia.liu" <Chuanjia.Liu@mediatek.com>,
- linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
- jianjun.wang@mediatek.com, linux-mediatek@lists.infradead.org,
- yong.wu@mediatek.com, bhelgaas@google.com,
- linux-arm-kernel@lists.infradead.org, amurray@thegoodpenguin.co.uk
-Sender: "Linux-mediatek" <linux-mediatek-bounces@lists.infradead.org>
-Errors-To:
- linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org
-
-From: "chuanjia.liu" <Chuanjia.Liu@mediatek.com>
-
-Remove unused property and add pciecfg node.
-
-Signed-off-by: chuanjia.liu <Chuanjia.Liu@mediatek.com>
----
- arch/arm/boot/dts/mt7629-rfb.dts | 3 ++-
- arch/arm/boot/dts/mt7629.dtsi | 23 +++++++++++++----------
- 2 files changed, 15 insertions(+), 11 deletions(-)
-
---- a/arch/arm/boot/dts/mt7629-rfb.dts
-+++ b/arch/arm/boot/dts/mt7629-rfb.dts
-@@ -176,9 +176,10 @@
- };
- };
-
--&pcie {
-+&pcie1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pcie_pins>;
-+ status = "okay";
- };
-
- &pciephy1 {
---- a/arch/arm/boot/dts/mt7629.dtsi
-+++ b/arch/arm/boot/dts/mt7629.dtsi
-@@ -368,16 +368,21 @@
- #reset-cells = <1>;
- };
-
-- pcie: pcie@1a140000 {
-+ pciecfg: pciecfg@1a140000 {
-+ compatible = "mediatek,mt7629-pciecfg", "syscon";
-+ reg = <0x1a140000 0x1000>;
-+ };
-+
-+ pcie1: pcie@1a145000 {
- compatible = "mediatek,mt7629-pcie";
- device_type = "pci";
-- reg = <0x1a140000 0x1000>,
-- <0x1a145000 0x1000>;
-- reg-names = "subsys","port1";
-+ reg = <0x1a145000 0x1000>;
-+ reg-names = "port1";
-+ mediatek,pcie-cfg = <&pciecfg>;
- #address-cells = <3>;
- #size-cells = <2>;
-- interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_LOW>,
-- <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>;
-+ interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>;
-+ interrupt-names = "pcie_irq";
- clocks = <&pciesys CLK_PCIE_P1_MAC_EN>,
- <&pciesys CLK_PCIE_P0_AHB_EN>,
- <&pciesys CLK_PCIE_P1_AUX_EN>,
-@@ -398,21 +403,19 @@
- power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
- bus-range = <0x00 0xff>;
- ranges = <0x82000000 0 0x20000000 0x20000000 0 0x10000000>;
-+ status = "disabled";
-
-- pcie1: pcie@1,0 {
-- device_type = "pci";
-+ slot1: pcie@1,0 {
- reg = <0x0800 0 0 0 0>;
- #address-cells = <3>;
- #size-cells = <2>;
- #interrupt-cells = <1>;
- ranges;
-- num-lanes = <1>;
- interrupt-map-mask = <0 0 0 7>;
- interrupt-map = <0 0 0 1 &pcie_intc1 0>,
- <0 0 0 2 &pcie_intc1 1>,
- <0 0 0 3 &pcie_intc1 2>,
- <0 0 0 4 &pcie_intc1 3>;
--
- pcie_intc1: interrupt-controller {
- interrupt-controller;
- #address-cells = <0>;
diff --git a/target/linux/mediatek/patches-5.4/1003-dts-mt7622-rfb-change-to-ax-mtd-layout.patch b/target/linux/mediatek/patches-5.4/1003-dts-mt7622-rfb-change-to-ax-mtd-layout.patch
deleted file mode 100644
index 74a294f098..0000000000
--- a/target/linux/mediatek/patches-5.4/1003-dts-mt7622-rfb-change-to-ax-mtd-layout.patch
+++ /dev/null
@@ -1,23 +0,0 @@
---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-@@ -589,17 +589,17 @@
-
- factory: partition@1c0000 {
- label = "Factory";
-- reg = <0x1c0000 0x0040000>;
-+ reg = <0x1c0000 0x0100000>;
- };
-
- partition@200000 {
- label = "firmware";
-- reg = <0x200000 0x2000000>;
-+ reg = <0x2c0000 0x2000000>;
- };
-
- partition@2200000 {
- label = "User_data";
-- reg = <0x2200000 0x4000000>;
-+ reg = <0x22c0000 0x4000000>;
- };
- };
- };
diff --git a/target/linux/mediatek/patches-5.4/1010-pcie-mediatek-fix-clearing-interrupt-status.patch b/target/linux/mediatek/patches-5.4/1010-pcie-mediatek-fix-clearing-interrupt-status.patch
deleted file mode 100644
index d3ef78dc72..0000000000
--- a/target/linux/mediatek/patches-5.4/1010-pcie-mediatek-fix-clearing-interrupt-status.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 4 Sep 2020 18:33:27 +0200
-Subject: [PATCH] pcie-mediatek: fix clearing interrupt status
-
-Clearing the status needs to happen after running the handler, otherwise
-we will get an extra spurious interrupt after the cause has been cleared
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/pci/controller/pcie-mediatek.c
-+++ b/drivers/pci/controller/pcie-mediatek.c
-@@ -616,10 +616,10 @@ static void mtk_pcie_intr_handler(struct
- if (status & INTX_MASK) {
- for_each_set_bit_from(bit, &status, PCI_NUM_INTX + INTX_SHIFT) {
- /* Clear the INTx */
-- writel(1 << bit, port->base + PCIE_INT_STATUS);
- virq = irq_find_mapping(port->irq_domain,
- bit - INTX_SHIFT);
- generic_handle_irq(virq);
-+ writel(1 << bit, port->base + PCIE_INT_STATUS);
- }
- }
-
diff --git a/target/linux/mediatek/patches-5.4/1011-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch b/target/linux/mediatek/patches-5.4/1011-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch
deleted file mode 100644
index 3f7660b14b..0000000000
--- a/target/linux/mediatek/patches-5.4/1011-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 4 Sep 2020 18:36:06 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for coherent DMA
-
-It improves performance by eliminating the need for a cache flush on rx and tx
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -357,7 +357,7 @@
- };
-
- cci_control2: slave-if@5000 {
-- compatible = "arm,cci-400-ctrl-if";
-+ compatible = "arm,cci-400-ctrl-if", "syscon";
- interface-type = "ace";
- reg = <0x5000 0x1000>;
- };
-@@ -969,6 +969,8 @@
- power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>;
- mediatek,ethsys = <&ethsys>;
- mediatek,sgmiisys = <&sgmiisys>;
-+ mediatek,cci-control = <&cci_control2>;
-+ dma-coherent;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -9,6 +9,7 @@
- #include <linux/of_device.h>
- #include <linux/of_mdio.h>
- #include <linux/of_net.h>
-+#include <linux/of_address.h>
- #include <linux/mfd/syscon.h>
- #include <linux/regmap.h>
- #include <linux/clk.h>
-@@ -2506,6 +2507,13 @@ static int mtk_hw_init(struct mtk_eth *e
- if (ret)
- goto err_disable_pm;
-
-+ if (of_dma_is_coherent(eth->dev->of_node)) {
-+ u32 mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
-+ ETHSYS_DMA_AG_MAP_PPE;
-+
-+ regmap_update_bits(eth->ethsys, ETHSYS_DMA_AG_MAP, mask, mask);
-+ }
-+
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) {
- ret = device_reset(eth->dev);
- if (ret) {
-@@ -3101,6 +3109,16 @@ static int mtk_probe(struct platform_dev
- }
- }
-
-+ if (of_dma_is_coherent(pdev->dev.of_node)) {
-+ struct regmap *cci;
-+
-+ cci = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
-+ "mediatek,cci-control");
-+ /* enable CPU/bus coherency */
-+ if (!IS_ERR(cci))
-+ regmap_write(cci, 0, 3);
-+ }
-+
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
- eth->sgmii = devm_kzalloc(eth->dev, sizeof(*eth->sgmii),
- GFP_KERNEL);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -448,6 +448,12 @@
- #define RSTCTRL_FE BIT(6)
- #define RSTCTRL_PPE BIT(31)
-
-+/* ethernet dma channel agent map */
-+#define ETHSYS_DMA_AG_MAP 0x408
-+#define ETHSYS_DMA_AG_MAP_PDMA BIT(0)
-+#define ETHSYS_DMA_AG_MAP_QDMA BIT(1)
-+#define ETHSYS_DMA_AG_MAP_PPE BIT(2)
-+
- /* SGMII subsystem config registers */
- /* Register to auto-negotiation restart */
- #define SGMSYS_PCS_CONTROL_1 0x0
diff --git a/target/linux/mediatek/patches-5.4/1012-pci-pcie-mediatek-add-support-for-coherent-DMA.patch b/target/linux/mediatek/patches-5.4/1012-pci-pcie-mediatek-add-support-for-coherent-DMA.patch
deleted file mode 100644
index 20a67676e3..0000000000
--- a/target/linux/mediatek/patches-5.4/1012-pci-pcie-mediatek-add-support-for-coherent-DMA.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 4 Sep 2020 18:42:42 +0200
-Subject: [PATCH] pci: pcie-mediatek: add support for coherent DMA
-
-It improves performance by eliminating the need for a cache flush for DMA on
-attached devices
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -805,6 +805,8 @@
- reg = <0 0x1a143000 0 0x1000>;
- reg-names = "port0";
- mediatek,pcie-cfg = <&pciecfg>;
-+ mediatek,hifsys = <&hifsys>;
-+ mediatek,cci-control = <&cci_control2>;
- #address-cells = <3>;
- #size-cells = <2>;
- interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_LOW>;
-@@ -822,6 +824,7 @@
- bus-range = <0x00 0xff>;
- ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>;
- status = "disabled";
-+ dma-coherent;
-
- slot0: pcie@0,0 {
- reg = <0x0000 0 0 0 0>;
-@@ -848,6 +851,8 @@
- reg = <0 0x1a145000 0 0x1000>;
- reg-names = "port1";
- mediatek,pcie-cfg = <&pciecfg>;
-+ mediatek,hifsys = <&hifsys>;
-+ mediatek,cci-control = <&cci_control2>;
- #address-cells = <3>;
- #size-cells = <2>;
- interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>;
-@@ -866,6 +871,7 @@
- bus-range = <0x00 0xff>;
- ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>;
- status = "disabled";
-+ dma-coherent;
-
- slot1: pcie@1,0 {
- reg = <0x0800 0 0 0 0>;
-@@ -925,6 +931,11 @@
- };
- };
-
-+ hifsys: syscon@1af00000 {
-+ compatible = "mediatek,mt7622-hifsys", "syscon";
-+ reg = <0 0x1af00000 0 0x70>;
-+ };
-+
- ethsys: syscon@1b000000 {
- compatible = "mediatek,mt7622-ethsys",
- "syscon";
---- a/drivers/pci/controller/pcie-mediatek.c
-+++ b/drivers/pci/controller/pcie-mediatek.c
-@@ -20,6 +20,7 @@
- #include <linux/of_address.h>
- #include <linux/of_pci.h>
- #include <linux/of_platform.h>
-+#include <linux/of_address.h>
- #include <linux/pci.h>
- #include <linux/phy/phy.h>
- #include <linux/platform_device.h>
-@@ -139,6 +140,11 @@
- #define PCIE_LINK_STATUS_V2 0x804
- #define PCIE_PORT_LINKUP_V2 BIT(10)
-
-+/* DMA channel mapping */
-+#define HIFSYS_DMA_AG_MAP 0x008
-+#define HIFSYS_DMA_AG_MAP_PCIE0 BIT(0)
-+#define HIFSYS_DMA_AG_MAP_PCIE1 BIT(1)
-+
- struct mtk_pcie_port;
-
- /**
-@@ -1068,6 +1074,27 @@ static int mtk_pcie_setup(struct mtk_pci
- }
- }
-
-+ if (of_dma_is_coherent(node)) {
-+ struct regmap *con;
-+ u32 mask;
-+
-+ con = syscon_regmap_lookup_by_phandle(node,
-+ "mediatek,cci-control");
-+ /* enable CPU/bus coherency */
-+ if (!IS_ERR(con))
-+ regmap_write(con, 0, 3);
-+
-+ con = syscon_regmap_lookup_by_phandle(node,
-+ "mediatek,hifsys");
-+ if (IS_ERR(con)) {
-+ dev_err(dev, "missing hifsys node\n");
-+ return PTR_ERR(con);
-+ }
-+
-+ mask = HIFSYS_DMA_AG_MAP_PCIE0 | HIFSYS_DMA_AG_MAP_PCIE1;
-+ regmap_update_bits(con, HIFSYS_DMA_AG_MAP, mask, mask);
-+ }
-+
- for_each_available_child_of_node(node, child) {
- int slot;
-
diff --git a/target/linux/mediatek/patches-5.4/1020-spi-nor-w25q512jv.patch b/target/linux/mediatek/patches-5.4/1020-spi-nor-w25q512jv.patch
deleted file mode 100644
index a234555556..0000000000
--- a/target/linux/mediatek/patches-5.4/1020-spi-nor-w25q512jv.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From: David Bauer <mail@david-bauer.net>
-Date: Thu, 11 Feb 2021 19:57:26 +0100
-Subject: [PATCH] mtd: spi-nor: add support for Winbond W25Q512
-
-The Winbond W25Q512 is a 512mb SPI-NOR chip. It supports 4K sectors as
-well as block protection and Dual-/Quad-read.
-
-Tested on: Ubiquiti UniFi 6 LR
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
-
-Ref: https://patchwork.ozlabs.org/project/linux-mtd/patch/20210213151047.11700-1-mail@david-bauer.net/
-
---- a/drivers/mtd/spi-nor/spi-nor.c
-+++ b/drivers/mtd/spi-nor/spi-nor.c
-@@ -2552,6 +2552,9 @@ static const struct flash_info spi_nor_i
- .fixups = &w25q256_fixups },
- { "w25q256jvm", INFO(0xef7019, 0, 64 * 1024, 512,
- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-+ { "w25q512jv", INFO(0xef4020, 0, 64 * 1024, 1024,
-+ SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ |
-+ SPI_NOR_HAS_TB | SPI_NOR_HAS_LOCK) },
- { "w25m512jv", INFO(0xef7119, 0, 64 * 1024, 1024,
- SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ) },
-
diff --git a/target/linux/mediatek/patches-5.4/1021-ubnt-ledbar-driver.patch b/target/linux/mediatek/patches-5.4/1021-ubnt-ledbar-driver.patch
deleted file mode 100644
index 41ab094e9f..0000000000
--- a/target/linux/mediatek/patches-5.4/1021-ubnt-ledbar-driver.patch
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/drivers/leds/Kconfig
-+++ b/drivers/leds/Kconfig
-@@ -824,6 +824,16 @@ config LEDS_LM36274
- Say Y to enable the LM36274 LED driver for TI LMU devices.
- This supports the LED device LM36274.
-
-+config LEDS_UBNT_LEDBAR
-+ tristate "LED support for Ubiquiti UniFi 6 LR"
-+ depends on LEDS_CLASS && I2C && OF
-+ help
-+ This option enables support for the Ubiquiti LEDBAR
-+ LED driver.
-+
-+ To compile this driver as a module, choose M here: the module
-+ will be called leds-ubnt-ledbar.
-+
- comment "LED Triggers"
- source "drivers/leds/trigger/Kconfig"
-
---- a/drivers/leds/Makefile
-+++ b/drivers/leds/Makefile
-@@ -85,6 +85,7 @@ obj-$(CONFIG_LEDS_LM3601X) += leds-lm36
- obj-$(CONFIG_LEDS_TI_LMU_COMMON) += leds-ti-lmu-common.o
- obj-$(CONFIG_LEDS_LM3697) += leds-lm3697.o
- obj-$(CONFIG_LEDS_LM36274) += leds-lm36274.o
-+obj-$(CONFIG_LEDS_UBNT_LEDBAR) += leds-ubnt-ledbar.o
-
- # LED SPI Drivers
- obj-$(CONFIG_LEDS_CR0014114) += leds-cr0014114.o
diff --git a/target/linux/mediatek/patches-5.4/115-dts-bpi64-add-snand-support.patch b/target/linux/mediatek/patches-5.4/115-dts-bpi64-add-snand-support.patch
deleted file mode 100644
index 4d369cefef..0000000000
--- a/target/linux/mediatek/patches-5.4/115-dts-bpi64-add-snand-support.patch
+++ /dev/null
@@ -1,57 +0,0 @@
---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-@@ -108,7 +108,7 @@
- };
-
- &bch {
-- status = "disabled";
-+ status = "okay";
- };
-
- &btif {
-@@ -283,14 +283,40 @@
- status = "disabled";
- };
-
--&nor_flash {
-+&snfi {
- pinctrl-names = "default";
-- pinctrl-0 = <&spi_nor_pins>;
-- status = "disabled";
-+ pinctrl-0 = <&serial_nand_pins>;
-+ status = "okay";
-
-- flash@0 {
-- compatible = "jedec,spi-nor";
-+ snand: spi_nand@0 {
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ compatible = "spi-nand";
-+ spi-max-frequency = <104000000>;
- reg = <0>;
-+
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ partition@0 {
-+ label = "bl2";
-+ reg = <0x0 0x80000>;
-+ read-only;
-+ };
-+
-+ partition@80000 {
-+ label = "fip";
-+ reg = <0x80000 0x200000>;
-+ read-only;
-+ };
-+
-+ partition@280000 {
-+ label = "ubi";
-+ reg = <0x280000 0x7d80000>;
-+ };
-+ };
- };
- };
-