aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mediatek/patches-5.4
diff options
context:
space:
mode:
authorDaniel Golle <daniel@makrotopia.org>2021-10-01 23:24:06 +0100
committerDaniel Golle <daniel@makrotopia.org>2021-10-01 23:28:24 +0100
commit6b434d3c44aced4c210b042a8791f8d14c407a49 (patch)
tree9a188b5090f3aac6d1fda3695c5e4f69508b9dc3 /target/linux/mediatek/patches-5.4
parent87623958b2796f69dcb7677e30ba5911b208f59a (diff)
downloadupstream-6b434d3c44aced4c210b042a8791f8d14c407a49.tar.gz
upstream-6b434d3c44aced4c210b042a8791f8d14c407a49.tar.bz2
upstream-6b434d3c44aced4c210b042a8791f8d14c407a49.zip
mediatek: remove files and patches for Linux 5.4
All subtargets only provide files and patches for Linux 5.10 by now so there is little use for the old Linux 5.4 stuff. Remove it. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
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>;
-+ };
-+ };
- };
- };
-